Compare the performance of if-else and switch statements in C#


[performance]

The example Compare the speeds of the conditional operator (ternary operator ?:) and the if-else statement in C# compares the performance of two kinds of conditional tests. Johnny Boy pointed out that this didn’t include another kind of conditional statement: switch. he also referred to another article that makes that comparison: C# .Net: What is the fastest conditional statement?. That article’s conclusion was if-else beats the others by a small amount.

But that’s not quite the whole story. The if-else and ?: constructs have very similar performance because they translate into the same kind of structure in IL code. However, the switch statement does something different. Instead of simply comparing its value to a sequence of other values one at a time, it builds a lookup table that lets it quickly jump to the appropriate part of the table for the value.

Incidentally Visual Basic doesn’t handle Select Case statements (the Visual Basic version of switch statements) in the same way. It converts Select Case statements into a sequence of If Then Else statements. That allows Visual Basic to add more features to Select Case. For example, a Case statement can include multiple values and ranges as in Case 0, 20, 40, 100 To 1000.

Anyway, because switch doesn’t actually compare its value to the case values, it can achieve better performance than if-else when conditions are right.

This example uses the following RunTrials method to compare a sequence of if-else statements to a switch statement.

// Run trials with a given number of values.
Stopwatch Watch = new Stopwatch();
Random Rand = new Random();
private void RunTrials(int num_values, int num_trials,
    TextBox txtIf, TextBox txtSwitch, TextBox txtDiff)
{
    Stopwatch watch = new Stopwatch();

    // if-then-else.
    Watch.Reset();
    Watch.Start();
    for (int trial = 0; trial < num_trials; trial++)
    {
        int result = -1;
        int value = Rand.Next(0, num_values);
        if (value == 0) result = 0;
        else if (value == 1) result = 1;
        else if (value == 2) result = 2;
        else if (value == 3) result = 3;
        ... More lines omitted ...
        else if (value == 49) result = 49;
        value = result;
    }
    Watch.Stop();
    double if_seconds = Watch.Elapsed.TotalSeconds;
    txtIf.Text = if_seconds.ToString("0.0000");
    txtIf.Refresh();

    // if-then-else.
    Watch.Reset();
    Watch.Start();
    for (int trial = 0; trial < num_trials; trial++)
    {
        int result = -1;
        int value = Rand.Next(0, num_values);
        switch (value)
        {
            case 0: result = 0; break;
            case 1: result = 1; break;
            case 2: result = 2; break;
            case 3: result = 3; break;
            ... More lines omitted ...
            case 49: result = 49; break;
        }
        value = result;
    }
    Watch.Stop();
    double switch_seconds = Watch.Elapsed.TotalSeconds;
    txtSwitch.Text = switch_seconds.ToString("0.0000");
    txtSwitch.Refresh();

    double diff = 100.0 * (if_seconds - switch_seconds) /
        if_seconds;
    txtDiff.Text = diff.ToString("0.0000");
    txtDiff.Refresh();
}

The num_values parameter indicates the number of values that might occur in a trial. For example, if num_values is 10, then the test uses numbers between 0 and 9. That means the if-else statements will finish after at most 10 statements. The switch statement always includes 50 case statements, although in this case it would only use the first 10.

For each trial, the method generates a random number within the desired range. It then uses that value to test a sequence of if-else statements.

After it has finished the if-else trials, the program repeats the trials for a switch statement.

If you look closely at the picture above, you'll see that the switch statement is faster than the if-else statements in every case with the percentage difference increasing as the range of values increases. That makes sense because the average time required to find a value by the if-else statements increases as the range of values increases. In contrast, the switch statement uses a lookup table so finding a particular item in the table should take roughly the same amount of time in every case.

The moral is, switch is faster if-else if you have a lot of cases to check, and the more cases you have the more time switch saves.

Even so, the total amount of time is quite small. In the picture above, the program ran 10 million trials so the difference when using 50 values was between 0.07 microseconds and 0.05 microseconds per test. Unless your code contains some extremely large loops, the difference in speed probably won't make a big difference. For that reason, you should usually pick whichever version makes your code easier to read and understand.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in performance, syntax and tagged , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *