63

I've been wondering this for some time now. I'm by far not a hardcore programmer, mainly small Python scripts and I've written a couple molecular dynamics simulations. For the real question: What is the point of the switch statement? Why can't you just use the if-else statement?

Thanks for your answer and if this has been asked before please point me to the link.

EDIT

S.Lott has pointed out that this may be a duplicate of questions If/Else vs. Switch. If you want to close then do so. I'll leave it open for further discussion.

Community
  • 1
  • 1
Nope
  • 34,682
  • 42
  • 94
  • 119
  • 1
    Duplicate: http://stackoverflow.com/questions/97987/switch-vs-if-else, http://stackoverflow.com/questions/395618/if-else-vs-switch – S.Lott Jan 16 '09 at 02:49
  • "couple molecular dynamics simulations" : - O And I guess you didn't use any switch statement in that :P Interesting – OscarRyz Jan 16 '09 at 03:21
  • 1
    Oscar, actually I didn't. Simulations can be complicated but not decision complicated, mainly math. – Nope Jan 16 '09 at 03:24
  • A very similar question was asked [here](http://stackoverflow.com/questions/445067/if-vs-switch-speed#445076). – Perpetualcoder Jan 16 '09 at 02:12
  • Tagged this as [tag:language-agnostic]. There are language-specific considerations and imitations. It was asked about Python, but the answers include C, C#, Java, Javascript, VB... – smci Oct 27 '16 at 22:26

8 Answers8

91

A switch construct is more easily translated into a jump (or branch) table. This can make switch statements much more efficient than if-else when the case labels are close together. The idea is to place a bunch of jump instructions sequentially in memory and then add the value to the program counter. This replaces a sequence of comparison instructions with an add operation.

Below are some extremely simplified psuedo-assembly examples. First, the if-else version:

    // C version
    if (1 == value)
        function1();
    else if (2 == value)
        function2();
    else if (3 == value)
        function3();

    // assembly version
    compare value, 1
    jump if zero label1
    compare value, 2
    jump if zero label2
    compare value, 3
    jump if zero label3
label1:
    call function1
label2:
    call function2
label3:
    call function3

Next is the switch version:

    // C version
    switch (value) {
    case 1: function1(); break;
    case 2: function2(); break;
    case 3: function3(); break;
    }

    // assembly version
    add program_counter, value
    call function1
    call function2
    call function3

You can see that the resulting assembly code is much more compact. Note that the value would need to be transformed in some way to handle other values than 1, 2 and 3. However, this should illustrate the concept.

Judge Maygarden
  • 26,961
  • 9
  • 82
  • 99
  • 1
    The assembly code you generate is valid only if you can make the cases of the same size. Actually, nop padding and multiplying value before adding could do something like that. But instead, normally jump tables are used, to get something "goto *table.124[value]" after a range check. – Blaisorblade Jan 16 '09 at 03:31
  • And in many cases, the indirect jump is much slower than a single since branch prediction for indirect branches is often less effective. – Blaisorblade Jan 16 '09 at 03:32
  • 2
    Fair enough, I wanted to keep it simple. Also, I believe the C switch statement predates branch-prediction, and he wanted to know why it exists... – Judge Maygarden Jan 16 '09 at 15:00
  • where would you not use switch and use if else? – mfaani Jan 16 '17 at 15:53
  • Doesn't this depend on the language? Some allow cases that aren't really any less complex than what you'd see in an if statement (e.g., a case where a regex matches the string). – Casey Jan 19 '17 at 15:44
24

Switch can be optimized by compiler - you will get faster code.
Also I find it to be more elegant when dealing with enumerable types.

To sum up switch statement gives you performance + code elegance :)

Here are some useful links:

aku
  • 122,288
  • 32
  • 173
  • 203
9

I'm ignoring this type of low level optimization as usually unimportant, and probably different from compiler to compiler.

I'd say the main difference is readability. if/else is very flexible, but when you see a switch you know right away that all of the tests are against the same expression.

Darron
  • 21,309
  • 5
  • 49
  • 53
8

For expressiveness, the switch/case statement allows you to group multiple cases together, for example:

case 1,2,3: do(this); break;
case 4,5,6: do(that); break;

For performance, compilers can sometimes optimize switch statements into jump tables.

jdigital
  • 11,926
  • 4
  • 34
  • 51
5

Besides the other mentioned Code readability and optimisation in .NET you also get the ability to switch on enums etc

enum Color { Red, Green, Blue }; 

Color c = Color.Red;

switch (c) // Switch on the enum

{

// no casting and no need to understand what int value it is

case Color.Red:    break;
case Color.Green:  break;
case Color.Blue:   break;

}
Justin King
  • 1,428
  • 12
  • 14
4

The ability to fall through several cases (intentionally leaving out the break statement) can be useful, and as a few people have already said it's faster as well. Perhaps the most important and least important consideration though, is that it just makes for prettier code than if/else. :)

Marc Charbonneau
  • 40,399
  • 3
  • 75
  • 82
2

Switch can be optimized "Better" by some compilers. There are pitfalls with using the switch statement in certain languages. In Java, the switch cannot handle strings and in VB2005 the switch statement will not work with radio buttons.
Switch can be faster and easier to read, If-Then is more generic and will work in more places.

WolfmanDragon
  • 7,851
  • 14
  • 49
  • 61
  • the if-then will work in more places? try this var sillyExample = true; switch (sillyExample) { case 3 > 2: console.log("lol"); break; case 0 !== 1: console.log("well i gues it BREAKS here"); } actually nvm that – cmarangu Nov 03 '19 at 06:26
-1

The only time switches can be faster are when your case values are constants, not dynamic or otherwise derived, and when the number of cases is significantly larger than the time to calculate a hash into a lookup table.

Case in point for Javascript, which compiles to assembly for execution on most engines, including Chrome's V8 engine, is that switch statements are 30%-60% slower to execute in the common case: http://jsperf.com/switch-if-else/20

Anthony Hildoer
  • 545
  • 3
  • 6
  • Here's adjusted benchmark: http://jsperf.com/switch-if-else/37. It makes the functions hot so that the optimizing compiler looks at them before the benchmark is ran. Just compiling to assembly is really not enough for anything. – Esailija Jun 06 '13 at 00:51
  • There are over 40 versions of that test now. Only version 37 shows switch statements faster, and just barely faster. In all the other versions of the test else-if is not just faster, its multiple times faster. This is proof that switch is only faster in edge cases, and even then only marginally faster. If we are going to make any blanket statements, its clear that "when in doubt, use else-if statements" is correct choice. – Anthony Hildoer Aug 09 '13 at 03:30
  • 3
    I already told you that my benchmark is set up in a way that enables browser optimizations for the tests. All other tests run unoptimized. Yes, in unoptimized code, elseif is faster. Who cares? Why would I care about the speed of unoptimized code? If you care, then that's fine by me but you should say that, because most people don't. Btw the reason for this is that the author of benchmark.js deliberately has code in place to try disable optimizations, not because you have to do something magical to enable optimizations. – Esailija Aug 09 '13 at 07:48
  • 4
    It is 10x faster in chrome for me, how is that barely? The differences between unoptimized and optimized code are so radical that if you didn't know about compiler optimizations, you wouldn't be able to explain the differences without sounding unauthentic. – Esailija Aug 09 '13 at 07:53
  • Wow, logical fallacy overload. I will cite them for you. The "for me" qualifier is irrelevant. See https://yourlogicalfallacyis.com/anecdotal You're cherry picking results. See https://yourlogicalfallacyis.com/the-texas-sharpshooter. There are over 40 iterations of the test. Only 1 of those iterations actually shows switch being faster more often. Lastly, you appeal to yourself indirectly as an authority because you "know about compiler optimization." See https://yourlogicalfallacyis.com/appeal-to-authority. Ironically, I got an A in compiler design while getting my master's of comp. sci. – Anthony Hildoer Aug 09 '13 at 16:00
  • 2
    *"Ironically, I got an A in compiler design while getting my master's of comp. sci."* That doesn't matter here. What matters is properly conducted performance tests or not (and a big number of badly made tests doesn't mean more than a small number of correctly made tests). – Denys Séguret Aug 09 '13 at 16:17
  • 2
    @AnthonyHildoer Yeah, you're right! It's impossible for 39 tests to be done wrong, especially for something like benchmarking, which is *sooo easy* and historically people have been *great* at making them! – Zirak Aug 09 '13 at 16:18
  • 2
    @AnthonyHildoer http://plover.net/~bonds/bdksucks.html You've committed the fallacy fallacy. – SomeKittens Aug 09 '13 at 16:22
  • Fine, lets ignore everything before iteration 37 and only look at the more recent iterations...all of which still support that switch statements are only more efficient in edge cases. Unless someone wants to point out why iterations 38+ don't accurately represent the usual case, be my guest. – Anthony Hildoer Aug 09 '13 at 16:51