czardas

Loop Optimal Performance

9 posts in this topic

#1 ·  Posted (edited)

I must have come across this difference in performance several times in the past, but I don't remember doing the actual test. Just to clear up any mystery, here's the test.

Local $iTime, $iStop = 1000000

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; first test the speed of For ... To ... Next
$iTime = TimerInit()
For $i = 1 to $iStop
    ; fastest
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($iTime & @LF)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; now test the speed of the same loop using While ... Wend
Local $iCount = 0
$iTime = TimerInit()
While $iStop > $iCount
    $iCount += 1
WEnd
$iTime = TimerDiff($iTime)
ConsoleWrite($iTime & @LF)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Now lets check the speed of Do ... Until
$iCount = 0
$iTime = TimerInit()
Do
    $iCount += 1
Until $iCount = $iStop
$iTime = TimerDiff($iTime)
ConsoleWrite($iTime & @LF)

Please ignore this topic. There was an error in the code giving incorrect results. I just woke up (sorry). The For . . . To . . . Next version is faster afterall.

 

Edited by czardas

Share this post


Link to post
Share on other sites



#2 ·  Posted

Here's what I get for a readout:

28.4433749625984 - For loop
498.253276143423 - While loop
487.562931401319 -  Do loop

The For loop, on my computer at least, EASILY beats out the other 2. The other 2 are usually within a few milliseconds of each other with the While loop winning over the Do loop most of the time.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks for testing. My first test was flawed because I used the 'less than' operator where I should have used the 'greater than' operator. The results were out by a mile. :whistle:

Edited by czardas

Share this post


Link to post
Share on other sites

#4 ·  Posted

Part of the difference in speed is the computation in the other 2 loops, and another chunk of time is done in the comparisons done in the Do and While loops.

If you add the computation to the For loop, you lose about 1-200 ms in speed. Adding an assignment and comparison statement to compare $iCount to $iStop, you lose about another 400 ms.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; first test the speed of For ... To ... Next
$iCount = 0
$iTime = TimerInit()
For $i = 1 To $iStop
    $iCount += 1 ; <<<<<<<<<<< adding a computation = 155.194737012467ms
;~  $iCount = ($iCount > $iStop)
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($iTime & @LF)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; first test the speed of For ... To ... Next
$iCount = 0
$iTime = TimerInit()
For $i = 1 To $iStop
;~  $iCount += 1
    $iCount = ($iCount > $iStop) ; Adding a comparison and assignment = 456.551773684589
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($iTime & @LF)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; first test the speed of For ... To ... Next
$iCount = 0
$iTime = TimerInit()
For $i = 1 To $iStop
    $iCount += 1
    $iCount = ($iCount > $iStop) ; adding both = 575.231495187727
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($iTime & @LF)

So, even though a straight out For loop is faster, what you're doing in the loops is probably going to make a whole lot more of a difference than just the loops themselves. After all, you're running the loops 1,000,000 times and even then you're only seeing a difference of maybe 400ms. That comes out to a difference of 0.0004 ms per iteration.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#5 ·  Posted

I totally concur with everything you just said. :)

Share this post


Link to post
Share on other sites

#6 ·  Posted

1 hour ago, BrewManNH said:

with the While loop winning over the Do loop most of the time

This seems odd to me, as it would seem that upon completion the While loop needs two extra jumps (first back to the top of the loop to evaluate the condition, then forward to beyond the loop). Or am I missing something?

Share this post


Link to post
Share on other sites

#7 ·  Posted

Benchmarking "naked" loops is not realistic imho because usually the performance killers are inside the loops. That means whether you use e.g. While/Wend or For/Next will make no real "feelable" difference.

But anyhow, "a nice to know" for the community.

1 person likes this

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#8 ·  Posted

8 hours ago, RTFC said:

This seems odd to me, as it would seem that upon completion the While loop needs two extra jumps (first back to the top of the loop to evaluate the condition, then forward to beyond the loop).

The While loop does it's comparison at the top of the loop, so when it gets to the $icount > $istop, it doesn't process the contents of the loop and just ends. The Do loop will always run through the loop at least once, even if the comparison is valid, so doing it at the end of the loop means the loop has to run at least one more time than the While loop.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

1 hour ago, BrewManNH said:

it doesn't process the contents of the loop and just ends.

Let me try to explain my point more clearly.;) The loop ends, but the programme then proceeds to the next statement, immediately below  the Wend that closes the loop. That is the extra forward jump I mentioned. And before this happens...

1 hour ago, BrewManNH said:

when it gets to the $icount > $istop

(NB the OP's While condition was actually "While $iStop > $iCount") This is the backward jump when reaching Wend, that precedes the final evaluation. So because the evaluation is done at the top of the looped block of statements, even though the counter increments within the loop to the point where it no longer satisfies the remain-in-loop-condition, the Wend forces it to jump back up to re-evaluate the counter, and upon failing the evaluation, the instruction pointer then jumps forward to the first statement below Wend.

In the Do-Until loop on the other hand, because the evaluation is done at the end of the looped block, when the leave condition is met no double jump needs to be performed as in While-Wend, and the IP just increments to below the Until statement. Therefore I would expect counter-based Do-Until loops to be faster on average than similarly structured While-Wend loops. (Of course, the point is academic beause For-Next is obviously far more efficient for counter-based loops than either of the other two).

Edited by RTFC

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now