Compare the performance of switch and if statements in C#

[performance]

This example compares the performance of switch and if-else statements. Both do roughly the same thing: they check a series of conditions until they find one that is true and then skip the rest. This example compares the speeds of these two constructs. When you click the Go button, the program executes the following code.

private void btnGo_Click(object sender, EventArgs e)
{
    // Get ready.
    txtIfThen.Clear();
    txtSwitch.Clear();
    this.Cursor = Cursors.WaitCursor;
    Refresh();
    int iterations = int.Parse(txtIterations.Text);
    DateTime start_time;
    TimeSpan elapsed;

    // If then.
    start_time = DateTime.Now;
    for (int i = 1; i <= iterations; i++)
    {
        for (int num = 0; num < 50; num++)
        {
            int value;
            if (num == 0) { value = num; }
            else if (num == 1) { value = num; }
            else if (num == 2) { value = num; }
            ...
            else if (num == 49) { value = num; }
            else { value = num; }
            if (value > 1000) Console.WriteLine(value);
        }
    }
    elapsed = DateTime.Now - start_time;
    txtIfThen.Text = elapsed.TotalSeconds.ToString() + " sec";
    txtIfThen.Refresh();

    // Switch.
    start_time = DateTime.Now;
    for (int i = 1; i <= iterations; i++)
    {
        for (int num = 0; num < 50; num++)
        {
            int value;
            switch (num)
            {
                case 0:
                    value = num; break;
                case 1:
                    value = num; break;
                case 2:
                    value = num; break;
                ...
                case 49:
                    value = num; break;
                default:
                    value = num; break;
            }
            if (value > 1000) Console.WriteLine(value);
        }
    }
    elapsed = DateTime.Now - start_time;
    txtSwitch.Text = elapsed.TotalSeconds.ToString() + " sec";
    txtSwitch.Refresh();

    this.Cursor = Cursors.Default;
}

After some preliminaries such as saving the starting time, the code loops over the desired number of iterations. For each iteration, the code loops over the values 1 through 50 and uses a series of if-then statements to find the loop’s value. It saves the value in a variable just to be sure that C# cannot optimize the statement out of existence.

After finishing the required number of iterations, the program repeats the same steps with a switch statement.

Because the two methods logically perform the same steps, I was surprised that the switch statement was so much faster. In the test shown here, the if-then statements took 2.03 seconds to perform 1 million iterations while the switch statement took only 0.32 seconds. I also tried a similar program with strings and, while both methods took much longer and the difference wasn’t as great (3.099 seconds and 1.193 seconds for 100,000 iterations), the switch statement was still much faster. I’ll leave making that version of the program as an exercise.

If you use ildasm to look at the IL code, you can see that the compiled code uses an IL switch statement to branch to a number of pre-computed locations depending on the switch variable’s value. (Although the compiler may not always generate a switch statement depending on the particular code.)

That’s the big catch. The values used by the switch statement must be calculatable at compile time. A series of if-then statements is much more flexible and can evaluate complicated expressions involving variables whose values can change at run time.

The conclusion is that if you have a long sequence of if-then statements as in this example, you’ll probably get better performance from the switch statement. If you need greater flexibility, then you need to use an if-else sequence.


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 *