Thanks to the suggestion of using GLOBAL variables instead of LOCAL ones I got the idea of optimizing this loop a little further. I read somewhere that FOR .. = .. UNTIL .. would be faster than using FOR .. = .. TO .., so I figured this might apply to other loops as well. Also we can do x:+1 instead of x = x + 1. I put it all togehter in a (rather dirty, I admit) program, and the results were quite interesting.
I will refer to FOR .. = .. TO .. / NEXT as FOR-TO and to FOR .. = .. UNTIL .. / NEXT as FOR-UNTIL from here on.
Here are the GLOBAL vs LOCAL results:
WHILE loop and x = x + 1...
LOCAL: 548 milliseconds
GLOBAL: 2374 milliseconds
REPEAT loop and x = x + 1...
LOCAL: 545 milliseconds
GLOBAL: 2365 milliseconds
WHILE loop and x :+ 1...
LOCAL: 514 milliseconds
GLOBAL: 2032 milliseconds
REPEAT loop and x :+ 1...
LOCAL: 816 milliseconds
GLOBAL: 2034 milliseconds
FOR-TO loop
LOCAL: 524 milliseconds
GLOBAL: 2023 milliseconds
FOR-UNTIL loop...
LOCAL: 512 milliseconds
GLOBAL: 2039 milliseconds
As it was already stated GLOBAL variables are *very much* slower than LOCAL ones.
I will now compare the different aspects in the WHILE and REPEAT loops.
These are the same results as before (exept FOR/NEXT loops), but grouped otherwise to make it easy to compare the difference between x = x + 1 and x:=1
Using LOCAL, WHILE loop
x=x+1: 548 milliseconds
x:+1: 514 milliseconds
Using GLOBAL, WHILE loop
x=x+1: 2374 milliseconds
x:+1: 2032 milliseconds
Using LOCAL, REPEAT loop
x=x+1: 545 milliseconds
x:+1: 816 milliseconds
Using GLOBAL, REPEAT loop
x=x+1: 2365 milliseconds
x:+1: 2034 milliseconds
You can see that using the shortcut (x:+1) is a bit faster than the old way, except for the LOCAL, REPEAT-loop thingy. This is a bit weird, but of course anything may be influenced by other processes. There were no programs active when I ran this test, but windows keeps a lot of background processes. It might be a nice thing to run this test several times to get a better avarage.
The first time I ran this thing I had one process taking up 100% of one virtual processor (p4 HT) and then the x:+1 was more than twice as fast! Don't know what exactly causes this.
Next thing up is the comparisation between WHILE and REPEAT loops. Of couse I'm using the same results.
Using LOCAL and x = x + 1...
WHILE: 548 milliseconds
REPEAT: 545 milliseconds
Using GLOBAL and x = x + 1...
WHILE: 2374 milliseconds
REPEAT: 2365 milliseconds
Using LOCAL and x :+ 1...
WHILE: 514 milliseconds
REPEAT: 816 milliseconds
Using GLOBAL and x :+ 1...
WHILE: 2032 milliseconds
REPEAT: 2034 milliseconds
As you see there is not much difference, exept for the LOCAL and x:+1. This result showed odd earlier.
Now we got the WHILE and REPEAT loops finished, let's see how the FOR loops behave!
Since we've already seen the difference between GLOBAL and LOCAL variables the only thing left to compare is FOR-TO and FOR-UNTIL. Behold:
Using LOCAL variables
FOR-TO: 524 milliseconds
FOR-UNTIL: 512 milliseconds
Using GLOBAL variables
FOR-TO: 2023 milliseconds
FOR-UNTIL: 2039 milliseconds
There is no clear difference between these two, but the difference that there is is rather small.
As a last thing to compare I have for you are all the results, ordered by speed.
Using LOCAL, FOR-UNTIL loop: 512 milliseconds
Using LOCAL, WHILE loop and x :+ 1: 514 milliseconds
Using LOCAL, FOR-TO loop: 524 milliseconds
Using LOCAL, REPEAT loop and x = x + 1: 545 milliseconds
Using LOCAL, WHILE loop and x = x + 1: 548 milliseconds
Using LOCAL, REPEAT loop and x :+ 1: 816 milliseconds
Using GLOBAL, FOR-TO loop: 2023 milliseconds
Using GLOBAL, WHILE loop and x :+ 1: 2032 milliseconds
Using GLOBAL, REPEAT loop and x :+ 1: 2034 milliseconds
Using GLOBAL, FOR-TO loop: 2039 milliseconds
Using GLOBAL, REPEAT loop and x = x + 1: 2365 milliseconds
Using GLOBAL, WHILE loop and x = x + 1: 2374 milliseconds
The conclusion so-far is rather easy: use FOR-UNTIL where possible ;)
These results are, however, statistically of not-so-much use, because it was just one test I ran. If I can find some time tonight (now I really need to get back to my database since I don't suppose my boss would like to see me toying with blitz all day ;) ) to do this more properly.
Of couse I won't let you go home without some source. It's a bit dirty and hastly-done, but clear.
Rem
this is a rather dumb but interresting example to benchmark various ways to do loops
the loops differ on the following subjects:
- the use of LOCAL and GLOBAL variables
- WHILE .. / WEND or REPEAT / UNTIL .. loops
- in case of WHILE / WEND or REPEAT / UNTIL loops the use of
the old-fashioned x = x + 1 or the new shortcut x:+ 1
- FOR .. = .. TO .. / NEXT or FOR .. = .. UNTIL .. / NEXT loops
it is of course based on the benchmark that this topic started with and
a few suggestions that were made.
EndRem
Strict
Local l:Int = 0 'l for local loop
Global g:Int = 0 'g for global loop
Local finish:Int 'moved finish declaration up so it won't consume any ticks while benchmarking
Local start:Int 'split declaration and the assigning of millisecs() so it looks a bit cleaner
'local variable, while loop, x = x + 1
Print "Using LOCAL, WHILE loop and x = x + 1..."
start = MilliSecs()
While (l < 1000000000)
l = l + 1
Wend
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
'global variable, while loop, x = x + 1
Print "Using GLOBAL, WHILE loop and x = x + 1..."
start = MilliSecs()
While (g < 1000000000)
g = g + 1
Wend
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
l = 0 'reset variables
g = 0
'local variable, repeat loop, x = x + 1
Print "Using LOCAL, REPEAT loop and x = x + 1..."
start = MilliSecs()
Repeat
l = l + 1
Until (l = 1000000000)
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
'global variable, repeat loop, x = x + 1
Print "Using GLOBAL, REPEAT loop and x = x + 1..."
start = MilliSecs()
Repeat
g = g + 1
Until (g = 1000000000)
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
l = 0 'reset variables
g = 0
'local variable, while loop, x :+ 1
Print "Using LOCAL, WHILE loop and x :+ 1..."
start = MilliSecs()
While (l < 1000000000)
l:+ 1
Wend
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
'global variable, while loop, x :+ 1
Print "Using GLOBAL, WHILE loop and x :+ 1..."
start = MilliSecs()
While (g < 1000000000)
g:+ 1
Wend
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
l = 0 'reset variables
g = 0
'local variable, repeat loop, x :+ 1
Print "Using LOCAL, REPEAT loop and x :+ 1..."
start = MilliSecs()
Repeat
l :+ 1
Until (l = 1000000000)
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
'global variable, repeat loop, x :+ 1
Print "Using GLOBAL, REPEAT loop and x :+ 1..."
start = MilliSecs()
Repeat
g :+ 1
Until (g = 1000000000)
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
'start for/next loops
'local variable, for-to loop
Print "Using LOCAL, FOR-TO loop"
start = MilliSecs()
For l = 0 To 1000000000
Next
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
'global variable, for-to loop
Print "Using GLOBAL, FOR-TO loop..."
start = MilliSecs()
For g = 0 To 1000000000
Next
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
'local variable, for-until loop
'because this is an until-loop, we need to loop until 1000000000 + 1 to be precise
Print "Using LOCAL, FOR-UNTIL loop..."
start = MilliSecs()
For l = 0 Until 1000000001
Next
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
'global variable, for-until loop, x = x + 1
'because this is an until-loop, we need to loop until 1000000000 + 1 to be precise
Print "Using GLOBAL, FOR-TO loop..."
start = MilliSecs()
For g = 0 Until 1000000001
Next
finish = MilliSecs()
Print "0 to 1 Billion in " + (finish - start) + " milliseconds"
Print
gameking: thanks for your suggestions, I will use them when I continue testing, alltough calculating before print and the declaration won't influence these benchmarks of course, because they happen 'outside' the time-tested code.
If 'strict' add overhead while executing I can't tell, but it's worth a try :)