Page 1 of 1
Counter without If/Endif
Posted: Tue Sep 27, 2005 2:54 pm
by va!n
Code updated For 5.20+
Using % (MODULO) to count any value! This is a nice way to optimize and "maybe speed up!?" your counter without the use of any If/Endif check!
Original version...
Code: Select all
lCountTo = 31 ; Only change the val (max you want to count)
lCountStep = 1
Repeat
lCountResult = lCountResult + lCountStep
If lCountResult > lCountTo
lCountResult = 0
EndIf
Debug lCountResult
Delay(100)
ForEver
Optimized version....
Code: Select all
lCountTo = 31
lCountStep = 1
Repeat
lCountResult = (lCountResult % lCountTo) + lCountStep
Debug lCountResult
Delay(100)
ForEver
Please dont change lCountStep! You can try to set "lCountStep = 2" and check the results... one loop the resutls are even and in the next loop they arent... maybe usefull or any special situation....
Posted: Tue Sep 27, 2005 6:12 pm
by fweil
Looks nice in reading, but use of % have a cost in CPU time I guess.
Rgrds
Posted: Tue Sep 27, 2005 7:35 pm
by Fred
yes, it uses a division op, which is a very expensive one. Speed wise, i think the if/endif method will beat it.
Posted: Tue Sep 27, 2005 9:08 pm
by va!n
Thanks for your reply, fweil and Fred!
@Fred:
You are right, the If/Endif methode is lightyears faster!
I had some time to do a small speed test.... here are the results...
a) MODULO = 266 ms
b) If/Endif = 47 ms
Code: Select all
lCountTo = 31 ; Only change the val (max you want to count)
lCountStep = 1
StartTime = GetTickCount_()
For i = 0 To 10000000
lCountResult = (lCountResult % lCountTo) + lCountStep
Debug lCountResult
Next
MessageRequester("Result:",Str(GetTickCount_()-StartTime))
Code: Select all
lCountTo = 31 ; Only change the val (max you want to count)
lCountStep = 1
StartTime = GetTickCount_()
For i = 0 To 10000000
lCountResult = lCountResult + lCountStep
If lCountResult > lCountTo
lCountResult = 0
EndIf
Debug lCountResult
Next
MessageRequester("",Str(GetTickCount_()-StartTime))
Posted: Wed Sep 28, 2005 9:49 am
by GedB
If you are using on of the powers of 2, like 8, 16, 32 or 64 you can get the result by masking with an &, which is very quick.
Using the following code I get the following results:
Code: Select all
lCountToMask = %00011111 ; 32 in binary
lCountStep = 1
StartTime = GetTickCount_()
For i = 0 To 10000000
lCountResult = (lCountResult & lCountToMask) + lCountStep
Debug lCountResult
Next
MessageRequester("And Result:",Str(GetTickCount_()-StartTime))
lCountTo = 32 ; Only change the val (max you want to count)
lCountStep = 1
StartTime = GetTickCount_()
For i = 0 To 10000000
lCountResult = (lCountResult % lCountTo) + lCountStep
Debug lCountResult
Next
MessageRequester("Mod Result:",Str(GetTickCount_()-StartTime))
lCountTo = 32 ; Only change the val (max you want to count)
lCountStep = 1
StartTime = GetTickCount_()
For i = 0 To 10000000
lCountResult = lCountResult + lCountStep
If lCountResult > lCountTo
lCountResult = 0
EndIf
Debug lCountResult
Next
MessageRequester("If Result:",Str(GetTickCount_()-StartTime))
Posted: Wed Sep 28, 2005 10:38 am
by va!n
here are my results... (x times tested and same results)
And: 47
Mod: 281
If: 47
Posted: Wed Sep 28, 2005 1:55 pm
by GedB
So theres no reason to obfuscate your code for the sake of performance.
The simplest code is a couple of nested fors. The codes intention couldn't be clearer and I get a speed result of 32.
Code: Select all
lCountTo = 32 ; Only change the val (max you want to count)
#lCountStep = 1
StartTime = GetTickCount_()
For i = 0 To 10000000 / lCountTo
For j = 1 To lCountTo Step #lCountStep
Debug j
Next j
Next i
MessageRequester("For Result:",Str(GetTickCount_()-StartTime))