moses-palmer / pynput

Sends virtual input commands
GNU Lesser General Public License v3.0
1.77k stars 245 forks source link

Improve performance by reducing ctypes calls #497

Closed BA-24 closed 1 year ago

BA-24 commented 2 years ago

From my testing (albeit with a quite heavily modified version of this script), this provides a roughly 30x performance boost with measurements taken from the first line of _modifier_state to the line after the layout_data assignment in __call__ for the unmodified version and from the first line of __call__ to the line after the layout_data assignment in __call__.

The test was conducting by pressing 4 regular keys (asdf), 4 shift keys ("!#¤), 2 more shift keys (() open and close parentheses) and then 2 ctrl+alt keys ([] open and close brackets). After this, I made a sum of all the measured times between the previously mentioned lines and compared those sums with each other.

From my research, there shouldn't be any problem with some keyboards having different shift/ctrl/alt keys since the vkCodes for these should be the same across all keyboard according this documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

IMPORTANT NOTE: This would also require a change to Listener._event_to_key in keyboard/_win32.py since it as of now does not pass "special keys" to KeyTranslator at all, however, I think that the KeyTranslator class should be the one to deal with those as well (especially since it already has access to the win32_vks.py module)

As a final note I would just like to say that I've enjoyed sifting through this project to extract the parts needed for my own and I want to thank everyone that has contributed to it

moses-palmer commented 2 years ago

Thank you very much for your contribution, and also your kind words!

While a 30x speedup is a great thing to achieve, I am not certain or is worth it in this case. The calls to GetAsyncKeyState are there to ensure that pynput has the same view of the modifier state as the kernel. If we maintain an internal view, I fear that it may diverge.

Have you noticed any performance issues in the code touched by this PR?

BA-24 commented 2 years ago

Hey, sorry for the late reply. I have not noticed any performance issues with that part specifically, however, I have had a similar issue to the one discussed here, however, I had the same issue using the Keyboard module so I wrote my own code (although a lot more simplistic and less feature-rich) to catch keyboard events and I've had no issues with it.

When writing my code, I decided to have it call a separate threaded function doing the actual handling/parsing of the input and then have the hook function return as quickly as possible as to reduce the latency to the rest of the system as much as possible.

That being said, I boiled down all the code to its bare minimum so it's hard to tell what made the difference.

If you want to check out my code here's a link to the page: https://github.com/antudic/QuicKCo It's specifically in the driver folder with the _listener.py program being responsible for inserting and removing the hooks and then I stole part of your KeyTranslator in win32.py as well, I hope you don't mind

Edit: Just wanted to mention that I am still quite new to using GitHub, I had no intention of closing this by "deleting the head repository" and I have no idea what consequences that will actually have.