altdesktop / i3ipc-python

🐍 An improved Python library to control i3wm and sway.
http://i3ipc-python.readthedocs.io
BSD 3-Clause "New" or "Revised" License
858 stars 108 forks source link

i3ipc is twice as slow as runnig `swaymsg -t get_tree` and parsing the json #203

Closed josch closed 6 days ago

josch commented 1 year ago

Hi,

the following is tested on Debian unstable with i3ipc 2.2.1:

$ time python3 -c 'import json; import subprocess; data = json.loads(subprocess.check_output(["swaymsg", "-t", "get_tree"]))'

real    0m0.155s
user    0m0.137s
sys 0m0.016s
$ time python3 -c "import i3ipc; i3ipc.Connection().get_tree()"

real    0m0.333s
user    0m0.297s
sys 0m0.033s

I think this is a bug. Spawning a subprocess and parsing its output should not be faster than using a dedicated library to do the job. And it should definitely not be twice as fast as using the library.

mgoral commented 6 days ago

TBH above test measures a lot of other things besides the get_tree(), namely the time of spawning Python interpreter, or importing modules. I prepared the following alternative test and cannot reproduce your results:

import timeit

n = 10

t = timeit.timeit("json.loads(subprocess.check_output(['swaymsg', '-t', 'get_tree']))", setup="import json; import subprocess", number=n)
print("JSON total:", t, "average:", t / float(n))

t = timeit.timeit("i3ipc.Connection().get_tree()", setup="import i3ipc", number=n)
print("i3ipc total:", t, "average:", t / float(n))

t = timeit.timeit("conn.get_tree()", setup="import i3ipc; conn = i3ipc.Connection()", number=n)
print("i3ipc with prepared Connection total:", t, "average:", t / float(n))

On my laptop (Framework 13 with AMD Ryzen 7640U, Debian Trixie with Python 3.12.6, i3ipc 2.2.1) I get the following results:

JSON total: 0.01668881200021133 average: 0.0016688812000211328
i3ipc total: 0.0038159750001796056 average: 0.00038159750001796053
i3ipc with prepared Connection total: 0.005930913000156579 average: 0.000593091300015658

which indicates that i3ipc is ~4.3x faster than parsing JSON.

josch commented 6 days ago

Thank you for looking into this.

It has been too long. I do not recall anymore my original motivation for this. In any case, here are my numbers:

JSON total: 0.14875912299612537 average: 0.014875912299612538
i3ipc total: 0.12046507900231518 average: 0.012046507900231518
i3ipc with prepared Connection total: 0.10878883700934239 average: 0.010878883700934238

Not as good as your but i3ipc is still faster than json. Thus, closing this.