Is there any significant difference between using if/else and switch-case in C#?


Question

What is the benefit/downside to using a switch statement vs. an if/else in C#. I can't imagine there being that big of a difference, other than maybe the look of your code.

Is there any reason why the resulting IL or associated runtime performance would be radically different?

1
203
5/23/2017 12:02:48 PM

Accepted Answer

SWITCH statement only produces same assembly as IFs in debug or compatibility mode. In release, it will be compiled into jump table (through MSIL 'switch' statement)- which is O(1).

C# (unlike many other languages) also allows to switch on string constants - and this works a bit differently. It's obviously not practical to build jump tables for strings of arbitrary lengths, so most often such switch will be compiled into stack of IFs.

But if number of conditions is big enough to cover overheads, C# compiler will create a HashTable object, populate it with string constants and make a lookup on that table followed by jump. Hashtable lookup is not strictly O(1) and has noticeable constant costs, but if number of case labels is large, it will be significantly faster than comparing to each string constant in IFs.

To sum it up, if number of conditions is more than 5 or so, prefer SWITCH over IF, otherwise use whatever looks better.

314
2/5/2017 5:19:30 AM

In general (considering all languages and all compilers) a switch statement CAN SOMETIMES be more efficient than an if / else statement, because it is easy for a compiler to generate jump tables from switch statements. It is possible to do the same thing for if / else statements, given appropriate constraints, but that is much more difficult.

In the case of C#, this is also true, but for other reasons.

With a large number of strings, there is a significant performance advantage to using a switch statement, because the compiler will use a hash table to implement the jump.

With a small number of strings, the performance between the two is the same.

This is because in that case the C# compiler does not generate a jump table. Instead it generates MSIL that is equivalent to IF / ELSE blocks.

There is a "switch statement" MSIL instruction that when jitted will use a jump table to implement a switch statement. It only works with integer types, however (this question asks about strings).

For small numbers of strings, it's more efficient for the compiler to generate IF / ELSE blocks then it is to use a hash table.

When I originally noticed this, I made the assumption that because IF / ELSE blocks were used with a small number of strings, that the compiler did the same transformation for large numbers of strings.

This was WRONG. 'IMA' was kind enough to point this out to me (well...he wasn't kind about it, but he was right, and I was wrong, which is the important part)

I also made a bone headed assumption about the lack of a "switch" instruction in MSIL (I figured, if there was a switch primitive, why weren't they using it with a hash table, so there must not be a switch primitive.... ). This was both wrong, and incredibly stupid on my part. Again 'IMA' pointed this out to me.

I made the updates here because it's the highest rated post, and the accepted answer.

However,I've made it Community Wiki because I figure I don't deserve the REP for being wrong. If you get a chance, please up vote 'ima''s post.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon