Counter without If/Endif

Share your advanced PureBasic knowledge/code with the community.
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Counter without If/Endif

Post 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! 8)

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....
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
fweil
Enthusiast
Enthusiast
Posts: 725
Joined: Thu Apr 22, 2004 5:56 pm
Location: France
Contact:

Post by fweil »

Looks nice in reading, but use of % have a cost in CPU time I guess.

Rgrds
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
Fred
Administrator
Administrator
Posts: 18253
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post 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.
va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Post 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 :cry:
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))
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post 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:
  • And: 31
    Mod: 375
    If: 47

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)) 

va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Post by va!n »

here are my results... (x times tested and same results)

And: 47
Mod: 281
If: 47
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post 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)) 
Post Reply