TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

C# If Versus Switch Performance

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

If vs. switch. 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.

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

Example. To start, this program declares two methods that are tested. One is called IsValidIf—it implements a selection with several if-statements. The second is called IsValidSwitch—it implements a selection as a switch.

Note: The results of the two methods on all inputs are equivalent—they have the same effects.

And: When this program is executed, the time required per call of each of those methods is reported.

C# program that tests if and switch performance

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]

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.

And: The if-statement is implemented with conditional branches. The jump table is faster—it requires fewer steps for certain inputs.

It is tempting to think that a switch is always faster than an equivalent if-statement. However, this is not true. A situation where the switch is slower is when the actual runtime of the program has a very skewed distribution of inputs.

Benchmark

So: If the input is almost always a specific value, then using an if-statement to test for that value may be faster.

Example 2. To continue, we look at a benchmark harness that tests two implementations. Method1 uses, internally, a switch statement. And Method2 uses an if-else if construct. The two methods have the same results.

Note: The methods receive the value zero 60% of the time. They receive the value one 40% of the time.

Tip: Method2 is most optimized for the value zero because it tests for it first.

C# program that tests switch and if

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]

We see that the two if-statements perform better. You save around 2 nanoseconds per method call. The intermediate language reveals that the switch-statement uses a "switch" opcode. The if-statements simply use branch opcodes.

Also: The exception logic was added to avoid inlining at the level of the JIT compiler.

JIT Method Test

Summary. 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.


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf