08-09-2022, 05:24 AM
Inspired by Phil's topic about _KEYHIT (Trying to understand keyhit function (qb64phoenix.com), I couldn't help but become curious myself about how often do we need to poll _KEYHIT? Phil's original routine had a limitless loop polling for key events, which is something that I personally *never* think is a good idea. Unthrottled loops are for processing things inside a program -- not for waiting for the user to complete some interaction! What happens if the user suddenly has someone show up at their door at the moment it enters one of these input-feedback loops? They're not there to actually press a key, so what you're dealing with is basically nothing much more than a DO: LOOP which is going to use 100% CPU power, run your PC hot, kick the fans in, use more electricity, and do *NOTHING* beneficial for you!!
Obviously, there should be some sort of limit in how often we check the keyboard for an input event, so my mind instantly begins to ask, "How many times is enough to keep up with reading the buffer, as much as the OS writes to it?" How often does your keyboard record a keypress, and how often does it report it to you? Does it report those events every 1/10 second? every 1/100th? 1/1000??
Honestly, I don't know!!
So, I wrote this little bit of code below to try and see how often my OS would report key events for me:
We start a loop, wait for a key to be pressed down to start a simple timer. Then we count how many keydown events are reported in that second. Finally, we report that number and clear the buffer to recount the process once again, until the user finally hits the ESC key to end the program.
For me, my keyboard on my laptop has a repeat rate of almost consistently 30 key hits per second. (I get reports of 30 and then 31 and then 30 and then 31.... Which seems to be an artifact of rounding and floating point numbers in my opinion.) I think if I set a DO LOOP like these to _LIMIT 30, there'd be almost no noticeable change in how this program works.
Try the first program and see what type of results you get. Try the second, with a _Limit 30 placed inside each loop and see if the performance changes much (if any at all) for you. For me, there's absolutely no difference in performance, leading me to think that if I'm running a program with an endless _KEYHIT loop like these, then there's absolutely no reason for me to run them with anything faster than a _LIMIT 30 in them. On my laptop at least, I don't seem to get keyhit events any faster than 30 times per second, so it really doesn't seem like I'd need to use CPU resources and run my program usage up beyond that point.
What I'm curious about now is other people's computers/OS. How often does your system update and report a keyhit event? Is there anyone who runs much higher with a repeat rate faster than 30 times per second? _Limit 30 works fine for me, but would it be throttling down someone else's system too much??
Honestly, if I was going to code this for a working program, I'd probably just make it a _LIMIT 60, and say "Good enough!!" with it. Twice what mine reports, so I figure that'll handle the majority of PCs out there and still not use an excessive amount of resources. Anyone higher than that, can just sort the code out and tweak it themselves. ;D
Obviously, there should be some sort of limit in how often we check the keyboard for an input event, so my mind instantly begins to ask, "How many times is enough to keep up with reading the buffer, as much as the OS writes to it?" How often does your keyboard record a keypress, and how often does it report it to you? Does it report those events every 1/10 second? every 1/100th? 1/1000??
Honestly, I don't know!!
So, I wrote this little bit of code below to try and see how often my OS would report key events for me:
Code: (Select All)
Do
Do
k = _KeyHit
Loop Until k > 0 'some key is pressed down to start the timer
t## = Timer
count = 0 'reset count between loops
Do
k = _KeyHit
If k > 0 Then count = count + 1 'increase the count rate based on the keyboard repeat/limit cycle
Loop Until Timer > t## + 1
Print count; "in 1 second"
_KeyClear
Loop Until k = 27
We start a loop, wait for a key to be pressed down to start a simple timer. Then we count how many keydown events are reported in that second. Finally, we report that number and clear the buffer to recount the process once again, until the user finally hits the ESC key to end the program.
For me, my keyboard on my laptop has a repeat rate of almost consistently 30 key hits per second. (I get reports of 30 and then 31 and then 30 and then 31.... Which seems to be an artifact of rounding and floating point numbers in my opinion.) I think if I set a DO LOOP like these to _LIMIT 30, there'd be almost no noticeable change in how this program works.
Code: (Select All)
Do
Do
k = _KeyHit
_Limit 30
Loop Until k > 0 'some key is pressed down to start the timer
t## = Timer
count = 0 'reset count between loops
Do
k = _KeyHit
If k > 0 Then count = count + 1 'increase the count rate based on the keyboard repeat/limit cycle
_Limit 30
Loop Until Timer > t## + 1
Print count; "in 1 second"
_KeyClear
Loop Until k = 27
Try the first program and see what type of results you get. Try the second, with a _Limit 30 placed inside each loop and see if the performance changes much (if any at all) for you. For me, there's absolutely no difference in performance, leading me to think that if I'm running a program with an endless _KEYHIT loop like these, then there's absolutely no reason for me to run them with anything faster than a _LIMIT 30 in them. On my laptop at least, I don't seem to get keyhit events any faster than 30 times per second, so it really doesn't seem like I'd need to use CPU resources and run my program usage up beyond that point.
What I'm curious about now is other people's computers/OS. How often does your system update and report a keyhit event? Is there anyone who runs much higher with a repeat rate faster than 30 times per second? _Limit 30 works fine for me, but would it be throttling down someone else's system too much??
Honestly, if I was going to code this for a working program, I'd probably just make it a _LIMIT 60, and say "Good enough!!" with it. Twice what mine reports, so I figure that'll handle the majority of PCs out there and still not use an excessive amount of resources. Anyone higher than that, can just sort the code out and tweak it themselves. ;D