Ok noobies, DoEvents is slow!!! Here's are faster methods:
Note to Moderators: If possible, can you make this a sticky?
That's right people. And it's no wonder why C++ programmers say VB is too slow. It's because the majority of the functions that come with VB are too slow, especially DoEvents.
What if I told you that you can not only do methods faster than DoEvents, but tame DoEvents and control it to your benefits. You tame it using the following API's
Code:
Private Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long
Private Declare Function SetPriorityClass Lib "kernel32" (ByVal hProcess As Long, ByVal dwPriorityClass As Long) As Long
Private Declare Function GetThreadPriority Lib "kernel32" (ByVal hThread As Long) As Long
'Private Declare Function GetPriorityClass Lib "kernel32" (ByVal hProcess As Long) As Long
Private Declare Function GetCurrentThread Lib "kernel32" () As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
And here's the code in action:
Note: This is not my code
DoEvents Tamer.zip
Ok now that you know how to tame DoEvents, let's do faster methods. How about the PeekMessage API:
Note: Also not my code:
PeekMessage API.zip
But are their faster methods. YES!!!
Code:
Private Declare Function GetInputState Lib "user32" () As Long
The GetInputState API is a whole lot faster. Unfortunately though, it only does events when an event has occured. Which means if a user does not press the keys on the keyboard or use the mouse, it will be like not using DoEvents in a loop until an input event has occured.
Here's a documentation on GetInputState as well as another API I will be discussing. And no I didn't write it:
DoEvents 100% Faster.doc
The best damn API I have ever used for DoEvents is GetQueueStatus
Code:
Private Declare Function GetQueueStatus Lib "user32" (ByVal qsFlags As Long) As Long
It happens to literally be 10 times faster than a regular DoEvents alone. Here is MY code, one I've wrriten myself, finally. This one does a simple performance test:
GetQueueStatus API.zip
And what I've learned in this performance test is this. Results may vary from computer to computer:
DoEvents
IDE - 192136
Exe - 296140
Comments: Slow, slugish, and ugly for realtime.
PeekMessage
IDE - 688950
Exe - 735468
Comments: Getting there. This is the method C++ commonly uses.
GetInputState
IDE - 965230
Exe - 1113434
Comments: Problem with this is that it's only active when an event has occured. With this I just simply held a key down.
GetQueueStatus
IDE - 947204
Exe - 1101420
Comments: It is fast and reliable. And you can add more events for it to check for too. It'll still be fast
Now are there other methods? There should be. Although I don't know myself. I hope you enjoyed this lengthy tutorial. I know I did! Comments and suggestions please.
Re: Ok noobies, DoEvents is slow!!! Here's are faster methods:
Have you seen Duncan (i.e. Merrion)'s code here:
http://www.vbforums.com/showthread.php?t=285335
Re: Ok noobies, DoEvents is slow!!! Here's are faster methods:
I got faster results on my dads computer! AMD Athlon 2.2 GHz
GetQueueStatus
IDE - 2284725
Exe - 3005472
Re: Ok noobies, DoEvents is slow!!! Here's are faster methods:
IDE / Compiled testing:
DoEvents = 2.5 Million - 2.6 Million
GetQueueStatus = 4.7 Million - 4.9 Million
PeekMessage = 24.9 Million - 27.3 Million
so PeekMessage seems to be much better!
Re: Ok noobies, DoEvents is slow!!! Here's are faster methods:
You don't have to call DoEvents many times in a loop.
For instance, if you have a loop of 1,000,000 iterations, do not call DoEvents 1,000,000, but call it every 1,000 iterations (or more).
Sample:
Code:
Dim c As Long
For c = 1 To 1000000
If (c Mod 1000) = 0 Then DoEvents
' code
Next c
That won't make DoEvents faster, but it will make the relative slowness unimportant.
There may be cases where you really need to call it very frequently, but in most cases not.
Re: Ok noobies, DoEvents is slow!!! Here's are faster methods:
Quote:
Originally Posted by
Eduardo-
You don't have to call DoEvents many times in a loop.
Yep, there's that...
And besides, DoEvents rarely "stands alone" (in a game-loop or something) -
but still "the myth's going strong" (that "DoEvents is slow" or "slows down your whole VB6-App").
Nobody of the Myth-followers seems to bother with calculating the time for a single DoEvents-Call,
which (according to bakas recent results) is around 400NanoSeconds on a current CPU.
So, if you have a GameLoop, which renders 100 Sprites:
Code:
Do Until Cancelled
Render100Sprites
DoEvents
Loop
And the Sprite-Rendering takes about 10MilliSeconds in each round (which would give around 100FPS),
then the "400NanoSeconds typically" (for the DoEvents-call) are entirely negligible.
(because the DoEvents-call increases the 10msec of the Sprite-rendering to only 10.0004msec as the "total time for a single loop-iteration")
Olaf
Re: Ok noobies, DoEvents is slow!!! Here's are faster methods:
that is true that any of the suggestions as well as DoEvents itself takes very little time.
with a stable fps loop (using direct2d or a sleep method or something else) would require (if we have 60 framerate) just 60 calls each second.
I have been working with my game for 3 years, using many different approaches,
even with that small time, after numerous tests DoEvents did create more stuttering when heavy animation/movement and software rendering.
using PeekMessage, made it "better", not perfect, since software rendering will never be perfect no matter what.
for a game, a stable loop, with exact time is very important, its the fluctuation that we want to limit as much possible.
- fps-wait-calculator
- render
- doevents
that doevents should not do anything, since we have fps-wait-calculator that would even out the doevents, but somehow, doevents works in a way that will affect the rendering anyway.
using PeekMessage, it seems it will not do that. dont ask me why, it just do, and for me the result is what counts.
that is why I think this thread is good, to give alternatives to DoEvents.
but nobody is forcing you to use it, if DoEvents works for you, fine, Im happy for you, I also want to use just that,
but for me, the PeekMessage alternative gave better results.