I don’t have an answer, but here is some advice:
• As a first step, try removing the print statements for your timing test. Instead, store timestamps in an array and print them after the test. As a general rule, timing tests which do as little work as necessary when measuring times are good.
• Your example code could be simplified, some variables are re-defined and some defined unnecessarily. Those issues should not introduce significant latencies, but they make your example more confusing than it needs to be.
• The only things that should matter with respect to getting accurate USB timestamps should be the USB ports version (1, 2 or 3) the underlying system APIs or libraries which you call from Python, the Python module which could introduce latencies (for example if it has its own internal event timer), and your USB input device. Also your own code and if your process/thread which reads the ports has priority. CPU and RAM should have nothing to do with it, unless you have something ridiculously low end, for example you are so low on memory the system is paging.
• Per the previous point, if you are reporting timing results, its good to describe all of the relevant conditions, such as the USB version, keyboard model, etc because your results depend on those; There are apparently fast and slow keyboards, or at least gamers seem to think so.
• I recently needed subject input from a gamepad and used a thread blocking on synchronous input from HIDAPI, expecting that should be low-latency. Alternate APIs for reading gamepads, PyGame and Pyglet, are both event based. I didn’t know what was going on inside of those and what latencies those event systems introduced. Note I have not actually measured any times yet so I am not certain that the expectation about blocking on HIDAPI input being fast is correct.
• Over on the Psychtoolbox Forum Denis Pelli points out from time-to-time that variance in subject response times is large relative to variance in USB response button latencies, and that therefore assumed requirements for super-precise input timing are often wrong. Be sure that you really do require the timing precision which you are after.
• Also, check to see what the Psychtoolbox does, the problem might already be have been studied and solved there and could be copied to Python.