C# If Versus Switch

Performance optimization

The performance of if and switch is rarely critical. But to increase your understanding of the execution engine, knowing some of the performance details is useful. We compare the performance of if-statements and switch-statements in various program contexts.

Notice: These benchmarks are of limited practical use. They are mainly useful when you are trying to determine when to choose switch instead of if.

Benchmark 1

To start, this program declares two methods that are tested: one is called IsValidIf, and it implements a selection with several if statements; the second is called IsValidSwitch, and it implements a selection as a switch. The results of the two methods on all inputs is equivalent. When this program is executed, the time required per call of each of those methods is reported.

This C# benchmark compares the performance of if and switch.

Program that tests if and switch performance [C#]

using System;
using System.Diagnostics;

class Program
{
    static bool IsValidIf(int i)
    {
	// Uses if-expressions to implement selection statement.
	if (i == 0 ||
	    i == 1)
	{
	    return true;
	}
	if (i == 2 ||
	    i == 3)
	{
	    return false;
	}
	if (i == 4 ||
	    i == 5)
	{
	    return true;
	}
	return false;
    }

    static bool IsValidSwitch(int i)
    {
	// Implements a selection statement with a switch.
	switch (i)
	{
	    case 0:
	    case 1:
		return true;
	    case 2:
	    case 3:
		return false;
	    case 4:
	    case 5:
		return true;
	    default:
		return false;
	}
    }

    const int _max = 100000000;
    static void Main()
    {
	bool b;
	var s1 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    b = IsValidIf(i);
	}
	s1.Stop();
	var s2 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    b = IsValidSwitch(i);
	}
	s2.Stop();
	Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
	    _max).ToString("0.00 ns"));
	Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
	    _max).ToString("0.00 ns"));
	Console.Read();
    }
}

Result: switch faster

3.83 ns [if]
2.88 ns [switch]
Note

Results. The if-statement method required an additional 1 nanosecond per method invocation. The switch implementation was faster. If you look at the intermediate code here, you will see that the switch uses a jump table opcode, while the if-statement is implemented with a series of conditional branches. The jump table is faster because it requires fewer steps for certain inputs.

Analysis. It may be tempting to think that a switch is always faster than an equivalent if-statement. However, this is not true. One situation where the switch is slower is when the actual runtime of the program has a very skewed distribution of inputs. If the input is almost always a specific value, then using an if-statement to test for that value may be faster because it will require only a single branch rather than a complex jump table.

Benchmark Programs

Benchmark 2

To continue, let's look at a benchmark harness that tests two implementations of the same method. Method1 uses, internally, a switch statement; Method2 uses an if-else if construct. The methods receive the value zero 60% of the time; they receive the value one 40% of the time. Method2 is most optimized for the value zero because it tests for it first.

Program that tests switch and if [C#]

using System;
using System.Diagnostics;

class Program
{
    const int _max = 100000000;
    static void Main()
    {
	Method1(0); // JIT.
	Method2(0); // JIT.

	var s1 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    Method1(0);
	    Method1(0);
	    Method1(0);
	    Method1(0);
	    Method1(0);
	    Method1(0);
	    Method1(1);
	    Method1(1);
	    Method1(1);
	    Method1(1);
	}
	s1.Stop();
	var s2 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    Method2(0);
	    Method2(0);
	    Method2(0);
	    Method2(0);
	    Method2(0);
	    Method2(0);
	    Method2(1);
	    Method2(1);
	    Method2(1);
	    Method2(1);
	}
	s2.Stop();
	Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
	    _max).ToString("0.00 ns"));
	Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
	    _max).ToString("0.00 ns"));
	Console.Read();
    }

    static int Method1(int val)
    {
	switch (val)
	{
	    case 0:
		{
		    return 1;
		}
	    case 1:
		{
		    return 3;
		}
	    default:
		{
		    throw new Exception();
		}
	}
    }

    static int Method2(int val)
    {
	if (val == 0)
	{
	    return 1;
	}
	if (val == 1)
	{
	    return 3;
	}
	throw new Exception();
    }
}

Result: if faster

39.81 ns [switch]
18.79 ns [if]
If keyword

Results. In this exploration, we see that the two if-statements perform better than the single switch statement. You save around 2 nanoseconds per method call by avoiding the switch statement. The intermediate language reveals that the switch statement uses a "switch" opcode, whereas the if statements simply use branch opcodes. Also, the exception logic was added to avoid inlining at the level of the JIT compiler.

If Statement

Summary

The C# programming language

In some cases, an equivalent switch statement is slower than an if-statement or chain of if-statements. Using frequency heuristics, you can optimize a fast path with an if-statement in many programs. Typically, the switch statement will perform better on value types, but not always.

Switch Statement
.NET