Optimizing If-Else Statements for best performance

Primary tabs

Do you ever have the desire to optimize your code as much as possible?
Do you have any cases where every nanosecond matters?
Do you use If statements?

This quick tip can help your code run slightly faster with no additional code.

We all know that for each command executed, there is a cost associated with it. Re-ordering your If Statements may lead to small performance gains (size of gains will depend on amount of iterations).

When using If Statements, putting your most likely case in the IF clause will yield the best performance. This is true because for each additional ElseIf clause that is added, all prior clauses must first be evaluated.

Based on my tests, given the following If Statement structure: Clause1...ClauseN-Else. The time to reach Clause1 will be fastest, followed by Clause2, etc... However, this pattern only repeats until ClauseN-1. Else will be slightly faster than ClauseN. It appears that the conditional jump from ClauseN to Else is less expensive than the jump from ClauseN to the end of the If statement, so Else is slightly less expensive than ClauseN. NOTE: See below for the case where N=1.

See the following test case and results:

When N>1:

ClassMethod Run2()
{
    For i=1:1:4 {
        Set time(i,"start")=$zh
        For j=1:1:1000000 {
            If i=1 {
                set a=1
            } ElseIf i=2 {
                set a=1
            } ElseIf i=3 {
                set a=1
            } Else {
                set a=1
            }
        }
        Set time(i,"end")=$zh
    }
    
    W "Time for If: ",time(1,"end")-time(1,"start")," seconds",!
    W "Time for ElseIf #1: ",time(2,"end")-time(2,"start")," seconds",!
    W "Time for ElseIf #2: ",time(3,"end")-time(3,"start")," seconds",!
    W "Time for Else: ",time(4,"end")-time(4,"start")," seconds",!
}

Time for If: .02166 seconds
Time for ElseIf #1: .026443 seconds
Time for ElseIf #2: .035915 seconds
Time for Else: .032695 seconds

When N=1:

ClassMethod Run()
{
    For i=1:1:2 {
        Set time(i,"start")=$zh
        For j=1:1:1000000 {
            If i=1 {
                set a=1
            } Else {
                set a=1
            }
        }
        Set time(i,"end")=$zh
    }
    
    W "Time for If: ",time(1,"end")-time(1,"start")," seconds",!
    W "Time for Else: ",time(2,"end")-time(2,"start")," seconds",!
}

Time for If: .02168 seconds
Time for Else: .015388 seconds

 

Based on these results, In the case where you have IF-Else, you should put your most common case in the Else Block. In the case where you use If-ElseIf-Else, you should put your most common case in the If Block.

As you can see, these numbers are relatively small compared to the 1 million iterations. However, if you are ever writing code that loops millions of times, reordering your If Statements can save you some time.

Replies

Interesting article.

Note that comparison with 1 would always be the fastest regardless of where it is:

Here's your code on my PC:

Time for If: .037652 seconds
Time for ElseIf #1: .045029 seconds
Time for ElseIf #2: .057766 seconds
Time for Else: .053267 seconds

And here's a modified code with comparison to 1 third:

ClassMethod Run3()
{
    For i=1:1:4 {
        Set time(i,"start")=$zh
        For j=1:1:1000000 {
            If i=3 {
                set a=1
            } ElseIf i=2 {
                set a=1
            } ElseIf i=1 {
                set a=1
            } Else {
                set a=1
            }
        }
        Set time(i,"end")=$zh
    }
    
    W "Time for If: ",time(1,"end")-time(1,"start")," seconds",!
    W "Time for ElseIf #1: ",time(2,"end")-time(2,"start")," seconds",!
    W "Time for ElseIf #2: ",time(3,"end")-time(3,"start")," seconds",!
    W "Time for Else: ",time(4,"end")-time(4,"start")," seconds",!
}

Running this code yields these results:

Time for If: .109513 seconds
Time for ElseIf #1: .048419 seconds
Time for ElseIf #2: .029746 seconds
Time for Else: .059306 seconds

Regardless of where comparison to 1 happens it would be the fastest one.

I have (2019.1.1CE) this is not confirmed:

i=1:1:4 {
  time(i,"start")=$zh
  f j=1:1:1e6 {
      i=2 {
        a=2
      ElseIf i=3 {
        a=3
      ElseIf i=1 {
        a=1
      Else {
        a=0
      }
  }
  time(i,"end")=$zh
}

"Time for If (i=2): ",time(1,"end")-time(1,"start")," seconds",!,
  "Time for ElseIf #1 (i=3): ",time(2,"end")-time(2,"start")," seconds",!,
  "Time for ElseIf #2 (i=1): ",time(3,"end")-time(3,"start")," seconds",!,
  "Time for Else (i=4): ",time(4,"end")-time(4,"start")," seconds",!

Time for If (i=2): .109283 seconds
Time for ElseIf #1 (i=3): .060785 seconds
Time for ElseIf #2 (i=1): .08026 seconds
Time for Else (i=4): .109974 seconds

Hi @Vitaliy Serdtsev ,

Try with larger numbers. With the smaller numbers, there will be slight variations which can flip the order.

With 1e9:

Time for If: 28.111261 seconds
Time for ElseIf #1: 38.782421 seconds
Time for ElseIf #2: 49.21395 seconds
Time for Else: 48.58113 seconds

Hi Peter.

Ok.

"Time for If (i=2): ",time(2,"end")-time(2,"start")," seconds",!,
  "Time for ElseIf #1 (i=3): ",time(3,"end")-time(3,"start")," seconds",!,
  "Time for ElseIf #2 (i=1): ",time(1,"end")-time(1,"start")," seconds",!,
  "Time for Else (i=4): ",time(4,"end")-time(4,"start")," seconds",!!

1e6
Time for If (i=2): .030974 seconds
Time for ElseIf #1 (i=3): .045126 seconds
Time for ElseIf #2 (i=1): .07144 seconds
Time for Else (i=4): .087353 seconds

1e9
Time for If (i=2): 28.59286 seconds
Time for ElseIf #1 (i=3): 43.044261 seconds
Time for ElseIf #2 (i=1): 82.277535 seconds
Time for Else (i=4): 69.212718 seconds

Also for your test, the same with my note for Eduard -  the output is hardcoded, so the first output line is for i=1, the second is for i=2, the third for i=3, the last for i=4

Hi Eduard,

Please note that the output is hardcoded, so your output for "Time for ElseIf #2" is actually for your If statement

 
And more food for thought: