420

I'm an ex Pascal guy, currently learning C#. My question is the following:

Is the code below faster than making a switch?

int a = 5;

if (a == 1)
{
    ....
}
else if(a == 2)
{
    ....
}
else if(a == 3)
{
    ....
}
else if(a == 4)
{
    ....
}
else
    ....

And the switch:

int a = 5;

switch(a)
{
    case 1:
        ...
        break;

    case 2:
        ...
        break;

    case 3:
        ...
        break;

    case 4:
        ...
        break;

    default:
        ...
        break;


}

Which one is faster?

I'm asking, because my program has a similar structure (many, many "else if" statements). Should I turn them into switches?

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
Ivan Prodanov
  • 34,634
  • 78
  • 176
  • 248
  • 88
    I feel compelled to note that you may be under-utilizing polymorphism in your designs if your code has a lot of these structures. – Greg D Apr 20 '09 at 11:21
  • 5
    See http://stackoverflow.com/questions/445067/if-vs-switch-speed – Dirk Vollmar Apr 20 '09 at 11:32
  • 4
    Switch is faster but unless you're hyper optimizing a tight loop, it doesn't mean anything. What is 37 nanoseconds vs 42 nanoseconds (made up numbers)? – Chris Marisic May 05 '16 at 14:18
  • I wonder how this differs when using logic at the case level eg (pseudo) `switch(true) case a==0; case a>0; case a<0;` etc – Jacksonkr Oct 19 '17 at 19:37
  • @Jacksonkr Java doesn't permit switching on values of type `boolean`. Also, the `case` expressions must be constant. – Kröw Jun 27 '19 at 21:33
  • @GregD Would you mind expanding on this comment? I know what polymorphism is as a concept but have little practice with it. How would you utilize it to help out in this situation? – rocksNwaves May 05 '21 at 13:47

14 Answers14

738

For just a few items, the difference is small. If you have many items you should definitely use a switch.

If a switch contains more than five items, it's implemented using a lookup table or a hash list. This means that all items get the same access time, compared to a list of if:s where the last item takes much more time to reach as it has to evaluate every previous condition first.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 123
    True, but with an if-else-if chain you can order the conditions based on how likely they are to be true. – Dave Van den Eynde Apr 20 '09 at 11:24
  • 85
    Yes, but the first 4-5 cases has to catch very close to 100% of the occurances to make up for the slower ones. – Guffa Apr 20 '09 at 12:36
  • 36
    Shouldn't most modern compilers optimize deep if/else if/else if/else if decision points as a switch/jump table? Which is to say; this shouldn't matter, the compiler's going to optimize it, why not just write the most readable code? – Dean J Aug 02 '10 at 13:51
  • 17
    @Dean J: Yes, generally you should write the most readable code even if the performance differs somewhat. If you need to optimise the code it may still make a difference. For the compiler to optimise the code the way that you describe, it has to have more knowledge about the value, i.e. knowing if reading the value multiple times has any side effects, as changing the code to a switch will only read the value once. – Guffa Aug 02 '10 at 14:55
  • 19
    From my point of view switch is also far more readable than if-elseif chain. which is also prone to errors such as mixing up if-else; if-else; in it which has other side effects. with switch you see n-fork right away, while with continous if-else-if-else it may be somewhat hidden. – aiodintsov Nov 26 '12 at 16:05
  • 3
    The mention of a lookup table here is dependent on the input data; for a string-based switch: sure, it'll be a hash-list; but for most integer-based switches (especially for contiguous candidates), it will be a direct IL `switch` – Marc Gravell Mar 19 '15 at 09:37
  • 2
    @MarcGravell: Yes, and the IL `switch` instruction is a lookup table. – Guffa Jun 06 '15 at 11:41
  • @Guffa But wouldn't a continous if/else if/else if/else just check one value as well? – Liggliluff Dec 30 '16 at 22:25
  • 5
    If the performance delta is negligible, I will always use a `switch()` statement. Have you ever tried to debug a massive `if()` statement tree in Visual Studio? You'll burn out your F10 button trying to figure out which `if()` statement is being matched; a `switch()` statement will take you to the matching case immediately. – Mass Dot Net Mar 22 '17 at 20:27
  • What is a "hash list"? I'm interested in how the compiler can generate a hash from the switch control variable into the domain of implemented cases, without collision, and efficiently. – MikeB Nov 28 '20 at 20:41
  • Does anyone knows what happens in java? Is this the same as C#? – CodeSlave Jun 07 '21 at 06:38
189

Why do you care?

99.99% of the time, you shouldn't care.

These sorts of micro-optimizations are unlikely to affect the performance of your code.

Also, if you NEEDED to care, then you should be doing performance profiling on your code. In which case finding out the performance difference between a switch case and an if-else block would be trivial.

Edit: For clarity's sake: implement whichever design is clearer and more maintainable. Generally when faced with a huge switch-case or if-else block the solution is to use polymorphism. Find the behavior that's changing and encapsulate it. I've had to deal with huge, ugly switch case code like this before and generally it's not that difficult to simplify. But oh so satisfying.

Wedge
  • 19,513
  • 7
  • 48
  • 71
  • 163
    I absolutely don't agree. You definitely should always care, not so much because of performance, but this also affects code readability and maintainability. And, as mentioned by others, you might well think about a better utilization of polymorphism. – Dirk Vollmar Apr 20 '09 at 12:53
  • 10
    Oh, I agree that you should always care about readability and maintainability. The proper way to rewrite a huge switch/case block is probably polymorphism (which, incidentally, is probably slightly slower, but you shouldn't care). Macro-optimization (good design) is always better than micro-optimization (faster statements). – Wedge Apr 20 '09 at 19:14
  • 2
    Agreed - if you have to care about this level of optimisation then you probably shouldn't be using a CLR-based managed language in the first place. – GrahamS Apr 27 '09 at 10:44
  • 5
    @GrahamS, That's a bit of a misnoma. virtual machines can be every bit as fast as "real" ones... not the least because the runtime can optimize much better than a compiler, because it can measure what actually needs optimizing. PS: My java solution to the Maze of Bolton takes 0.03375655565 seconds. The published winning C# solution takes 0.166 seconds, with C++ in second place at 429.46 seconds to find the incorrect answer. And CLR is inherently slow? Hmmm... I don't think so Tim ;-) – corlettk May 18 '09 at 11:58
  • 10
    The type of thinking "You never need to care becuase peformance is never an issue". How can any programmer even consider this? as a programmer you need to know what happens under the hood, knowing the compiler and use the most of it, becues one day those extra MS might save your day. Coming from C++ i see a lot of this thinking and behaviour in C# and it´s a shame. Rather answer his question then disregarding it. – Tordin Mar 08 '17 at 12:51
  • 2
    Consider a more general case where you are writing a function that is going to be called >100k times. I tend to call these "multipliers". For example, an if-statement in a for loop in a recursive function has 2 multipliers from both the loop and function. A small improvement to the body of the if-statement can net a HUGE performance boost. Thinking like this while designing can help prevent problems down the line that would cause you to have to use a profiling tool. This is a legit question, and should not be disregarded. – wizard07KSU Jun 13 '17 at 22:28
  • 2
    @wizard07KSU 100k? 100k if/else comparisons in c# might net you a single millisecond of execution time, only a fraction of which is made up of the if/else comparisons. As I said, if you have performance critical code then trying to guess which method of optimization will be the best is incorrect, you need to profile your code. Don't try to shave nanoseconds off a block of code unless you need to. – Wedge Jun 14 '17 at 23:21
  • 4
    Horrible answer. – wild_nothing Jun 21 '17 at 09:12
  • 1
    Why OP cares is irrelevant. What's also irrelevant is also this answer, as it doesn't answer the question at all. Weird how this has hunderds of upvotes and yet SO has always emphasized staying on topic and answering the question. – Amir Asyraf Nov 05 '20 at 10:09
34

Believing this performance evaluation, the switch case is faster.

This is the conclusion:

The results show that the switch statement is faster to execute than the if-else-if ladder. This is due to the compiler's ability to optimise the switch statement. In the case of the if-else-if ladder, the code must process each if statement in the order determined by the programmer. However, because each case within a switch statement does not rely on earlier cases, the compiler is able to re-order the testing in such a way as to provide the fastest execution.

Michael Klement
  • 3,376
  • 3
  • 30
  • 34
18

Another thing to consider: is this really the bottleneck of your application? There are extremely rare cases when optimization of this sort is really required. Most of the time you can get way better speedups by rethinking your algorithms and data structures.

Vilx-
  • 104,512
  • 87
  • 279
  • 422
12

Switch is generally faster than a long list of ifs because the compiler can generate a jump table. The longer the list, the better a switch statement is over a series of if statements.

Steven
  • 3,878
  • 3
  • 21
  • 21
  • 3
    Noet that the jump-table only applies (IIRC) for contiguous values. It is not uncommon for the compiler to emit a mix of jump-tables and breq for complex non-contiguous options. – Marc Gravell Apr 20 '09 at 11:15
10

I'd say the switch is the way to go, it is both faster and better practice.

Here is a link that shows benchmark tests comparing the two.

Marcello B.
  • 4,177
  • 11
  • 45
  • 65
Shaun Bohannon
  • 491
  • 1
  • 4
  • 11
8

Shouldn't be hard to test, create a function that switches or ifelse's between 5 numbers, throw a rand(1,5) into that function and loop that a few times while timing it.

Ólafur Waage
  • 68,817
  • 22
  • 142
  • 198
6

I'm not sure, but i believe the speed of one or the other changes depending on the programming language you're using.

I usually prefer to use switch. That way the code is simplear to read.

user308693
  • 69
  • 1
  • 1
  • 2
    Funny, I think if else is cleaner :D I reckon go with whatever is most readable. – Johnny Rockex Oct 14 '21 at 04:40
  • Same here. 'else if' is easier to read and write. switch case break etc... too much stuff on there. My benchmarking on Arduino shows 'else if' is faster. So does this guy here on github here. https://github.com/nezumi-tech/if_elseif_vs_switch_case_on_Arduino_Mega I guess the answer to this depends on what you are coding. – Noel Mar 27 '22 at 10:32
6

Technically, they produce the exact same result so they should be optimizable in pretty much the same way. However, there are more chances that the compiler will optimize the switch case with a jump table than the ifs.

I'm talking about the general case here. For 5 entries, the average number of tests performed for the ifs should be less than 2.5, assuming you order the conditions by frequency. Hardly a bottleneck to write home about unless in a very tight loop.

jfclavette
  • 3,457
  • 2
  • 20
  • 17
6

switch usually gets translated into a lookup table by the compiler, if possible. So lookup of an arbitrary case is O(1), instead of actually doing a few case comparisons before finding the one you want.

So in many cases an if/else if chain will be slower. Depending on the frequency with which your cases are being hit that may make no difference, though.

Joey
  • 344,408
  • 85
  • 689
  • 683
5

Far more important than the performance benefits of switch (which are relatively slight, but worth noting) are the readability issues.

I for one find a switch statement extremely clear in intent and pure whitespace, compared to chains of ifs.

annakata
  • 74,572
  • 17
  • 113
  • 180
4

Short answer: Switch statement is quicker

The if statement you need two comparisons (when running your example code) on average to get to the correct clause.

The switch statement the average number of comparisons will be one regardless of how many different cases you have. The compiler/VM will have made a "lookup table" of possible options at compile time.

Can virtual machines optimize the if statement in a similar way if you run this code often?

AnnaR
  • 3,166
  • 6
  • 35
  • 39
2

see http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.switch%28VS.71%29.aspx

switch statement basically a look up table it have options which are known and if statement is like boolean type. according to me switch and if-else are same but for logic switch can help more better. while if-else helps to understand in reading also.

User42590
  • 2,473
  • 12
  • 44
  • 85
2

Since the switch statement expresses the same intent as your if / else chain but in a more restricted, formal manner, your first guess should be that the compiler will be able to optimize it better, since it can draw more conclusions about the conditions placed on your code (i.e. only one state can possibly be true, the value being compared is a primitive type, etc.) This is a pretty safe general truth when you are comparing two similar language structures for runtime performance.

mqp
  • 70,359
  • 14
  • 95
  • 123