Page 1 of 1
IF vs SELECT speed test
Posted: Sat Feb 08, 2025 7:45 pm
by minimy
Was looking to improve speed in an old basic Atom cpu laptop and did this program to test speed IF vs SELECT.
I put it as an anecdote, I found it interesting
RESULT WAS:
SELECT: 470ms
IF: 434ms
And the winner is IF
In the I7 i cant see
Code: Select all
DisableDebugger
t= ElapsedMilliseconds()
For p= 1 To 10000000
a= Random(10,1)
Select a
Case 1
b=a
Case 2
b=a
Case 3
b=a
Case 4
b=a
Case 5
b=a
Case 6
b=a
Case 7
b=a
Case 8
b=a
Case 9
b=a
Case 10
b=a
EndSelect
Next p
t1= ElapsedMilliseconds()-t
t= ElapsedMilliseconds()
For p= 1 To 10000000
a= Random(10,1)
If a=1
b=a
ElseIf a=2
b=a
ElseIf a=3
b=a
ElseIf a=4
b=a
ElseIf a=5
b=a
ElseIf a=6
b=a
ElseIf a=7
b=a
ElseIf a=8
b=a
ElseIf a=9
b=a
ElseIf a=10
b=a
EndIf
Next p
t2= ElapsedMilliseconds()-t
MessageRequester("TEST","IF vs SELECT"+#CR$+"SELECT: "+Str(t1)+#CR$+"IF: "+Str(t2))
Re: IF vs SELECT speed test
Posted: Sat Feb 08, 2025 10:26 pm
by mk-soft
Another one compare these unnecessary.
The compiler makes the best of it anyway (optimisation)
If and Select 40 ms equal
I find Select clearer than several If and Elseif
Re: IF vs SELECT speed test
Posted: Sat Feb 08, 2025 11:31 pm
by idle
you won't see much difference as the generated code is much the same.
Re: IF vs SELECT speed test
Posted: Sun Feb 09, 2025 2:27 am
by STARGĂ…TE
Keep also in mind that the CPU is "waked up" after the first loop und runs at higher frequencies in the second loop.
If you first measure the IF and then the SELECT part, SELECT is the winner
In any case, both constructs are equal fast.
Your code:
---------------------------
TEST
---------------------------
IF vs SELECT
SELECT: 134
IF: 131
---------------------------
OK
---------------------------
Swap both loops:
---------------------------
TEST
---------------------------
IF vs SELECT
SELECT: 132
IF: 135
---------------------------
OK
---------------------------
Re: IF vs SELECT speed test
Posted: Sun Feb 09, 2025 3:18 am
by AZJIO
The Random() function is not a good solution for checking the exact speed. RandomSeed() is required.
Re: IF vs SELECT speed test
Posted: Sun Feb 09, 2025 11:24 am
by SMaag
The difference between If ans Select in the Assembley
Code: Select all
; If a=1
MOV r15,qword [v_a]
CMP r15,1
JNE _EndIf4
; b=a
PUSH qword [v_a]
POP qword [v_b]
; ElseIf a=2
JMP _EndIf3
_EndIf4:
MOV r15,qword [v_a]
CMP r15,2
JNE _EndIf5
; b=a
PUSH qword [v_a]
POP qword [v_b]
; ElseIf a=3
JMP _EndIf3
_EndIf5:
MOV r15,qword [v_a]
CMP r15,3
JNE _EndIf6
; b=a
PUSH qword [v_a]
POP qword [v_b]
; ElseIf a=4
; Select a
PUSH qword [v_a]
; Case 1
MOV r15,1
CMP r15,[rsp]
JNE _Case1
; b=a
PUSH qword [v_a]
POP qword [v_b]
; Case 2
JMP _EndSelect1
_Case1:
MOV r15,2
CMP r15,[rsp]
JNE _Case2
; b=a
PUSH qword [v_a]
POP qword [v_b]
; Case 3
JMP _EndSelect1
_Case2:
MOV r15,3
CMP r15,[rsp]
JNE _Case3
; b=a
PUSH qword [v_a]
POP qword [v_b]
; Case 4
JMP _EndSelect1
With changing the Loop Constructions For, Repeat While, or If, Select you can't change the speed!
removing jumps or Procedurecalls is much more effective. Unrolling Loops is a way to speed up.
If you show more of the code, we can analyse it and maybe find some bottleneck!
Re: IF vs SELECT speed test
Posted: Sun Feb 09, 2025 10:49 pm
by idle
timing If's and Selects isn't really that useful outside of the context of a more complex program.
When the CPU encounters an IF it will generally assume that the 1st clause is the desired outcome but after a few loops it will also have tried to guess which branch is the preferred outcome it's self but setting the 1st clause as being the desired one is the better option for cache coherency and will lead to less cache hits. Also if you have independent code in the branches, you will also get the benefit of out of order executions and essentially you can get your else for free as the cpu will process the branches in parallel and then give you the result, though it's often hard to make the code independent.
Fortunately you don't really need to be so concerned about the code layout now as the c optimizer will try to eliminate branches, swap them around, unroll loops and inline procedures and the more native code you write, the more chance it will have at optimizing it. Then there's also LTO (link time optimizer) where the linker can rearrange lib functions to reduce cache hits again.
Re: IF vs SELECT speed test
Posted: Mon Feb 10, 2025 4:49 am
by AZJIO
SMaag wrote: Sun Feb 09, 2025 11:24 am
removing jumps or Procedurecalls is much more effective.
I do not agree. Eliminating the calls of functions makes the code unreadable, and all this for the sake of one nanosecond, it is inappropriate.
Code: Select all
DisableDebugger
EnableExplicit
Procedure Test()
Protected x = 1
EndProcedure
Define StartTime, i
StartTime = ElapsedMilliseconds()
For i = 0 To 10000000
Test()
Next
StartTime = ElapsedMilliseconds() - StartTime
EnableDebugger
Debug StartTime
Re: IF vs SELECT speed test
Posted: Mon Feb 10, 2025 12:39 pm
by SMaag
I do not agree. Eliminating the calls of functions makes the code unreadable, and all this for the sake of one nanosecond, it is inappropriate.
yes absolutley right!
But inlining short functions or use Macros instead seeds up! I agree, it only makes sense if you have regulary millions of calls. Like in Pixel operations or data sience ...
Think about such things only if you see your program is to slow. Under a execution time of a second, the user won't feel it.
Code: Select all
DisableDebugger
EnableExplicit
Procedure Add(x, n)
ProcedureReturn x + n
EndProcedure
#Mio = 1000000
#Loops = #Mio * 10
Define t1, t2, i, sum
; first a loop to startup CPU! eliminates first test is solower
For I = 1 To 10000
sum+I
Next
I = 0
t1 = ElapsedMilliseconds()
For i = 0 To #Loops
Add(sum,I)
Next
t1 = ElapsedMilliseconds() - t1
sum = 0
t2 = ElapsedMilliseconds()
For i = 0 To #Loops
sum + i
Next
t2 = ElapsedMilliseconds() - t2
EnableDebugger
OpenConsole()
PrintN("With Proc = " + Str(t1))
PrintN("Inline = " + Str(t2))
Print("Press a key to exit")
Input()