23

From what I have read I can summarize,

  • Switch case is implementation defined but is mostly defined as a jump table
  • Switch case makes the code more readable
  • Switch is faster than if/elseif (?)

Consider a case where I have 300+ switch cases. I know an if/elseif in this scene will be a mess.

But I want to know how will a switch case perform in such a scene?

  • Is it scalable i.e it remains relatively faster than an if/else no matter how many cases are present ?
  • Since it is implementation defined how can I figure out how my compiler is implementing it?
  • And above all how do I do this if/elseif - switch comparison apart from actually writing the code and using a profiler? I have tried compiling a small .c file with switch case using gcc 4.8.1 -S switch and it looks like a jump table is created.Where do I go from here?
  • Is it better/worse to use an if/elseif in such scenarios

I am primarily interested in C/C++ specific details

20
  • 8
    Most of modern compilers would optimize a bunch of if's into a jump table anyway, so you will not notice any difference. One could also argue that if you have to make 300 if conditions in one place, your code is badly designed Commented Feb 5, 2015 at 9:17
  • 1
    @SingerOfTheFall Yes I would agree with the ill designed part.It is a legacy code and from its use case i.e runtime choosing of subclass based on the switch condition maybe it was most feasible Commented Feb 5, 2015 at 9:22
  • 2
    How does switch perform? Measure it! Is it scalable? Yes, the worst case is like chain of if/else. How is compiler implementing switch? Look at the generated assembly code. It's not always jump table. If the values in case labels are far apart (e.g. case 1, case 10000, case 90000), then switch is converted to series of if/else or mix of if/else and jump table. Is if/else better than switch? Measure it. Commented Feb 5, 2015 at 9:24
  • 23
    If you have 300+ switch cases, what you need is refactoring.
    – rubikonx9
    Commented Feb 5, 2015 at 9:28
  • 1
    @Suvarna The more interesting question to pose to the community would be how to fix this ill-designed code so that you don't need either the switch or the if/elseif chain. I look forward to seeing that question :) Commented Feb 5, 2015 at 9:29

4 Answers 4

26

The compiler might decide to use a jump table and make a huge improvement in the case of 300+.

Compilers do make optimizations over branches using various techniques like decision trees .

The more easy is for a compiler to understand the code, the better. And the switch statement is more readable for the compiler as well.

Think about the else if from a compilers point of view . It would look like an arrowhead :

    - if 
     - else
      - else 
       - else
        - else

You need to evaluate each previous if in order to get to the correct else .

However a Switch looks more like a block :

     - case
     - case
     - case
     - case

So the compiler can sometimes determine where to go directly.

For your bullet questions :

  1. it is scalable. It's easy to be written by the developers and if the compiler uses jump tables adding more cases won't affect.

  2. it's up to the compiler to decide what to use. It might choose to not optimize it at all (but most likely jump tables).

  3. You can run a loop and meassure times by hand maybe ?

  4. It's always better to use switch. The worst case scenario the switch will act just as an if/else .

8
  • 3
    "It's always better to use switch." In performance, yes. In readability and potential for programmer error, no. Commented Feb 5, 2015 at 17:06
  • Why can't a compiler determine that a given set of if..else statements are logically equivalent to a switch, and optimize accordingly?
    – PythonNut
    Commented Feb 5, 2015 at 19:31
  • 1
    @PaulDraper: Even in terms of performance, a chain of if statements may be better if each if ends up being true roughly half the time it's executed (so half of the items satisfy the first if, a quarter satisfy the second, an satisfy the third, etc. Obviously that exponential decay is not going to continue for 300 items, but using if statements for the parts of the list which represent the most frequent usage cases can sometimes be a significant win as compared with a switch.
    – supercat
    Commented Feb 5, 2015 at 22:57
  • @PythonNut, a sufficiently smart compiler certainly can. The mostly likely reason it wouldn't is that the programmer inadvertently wrote the if-else in a way that is not convertible by the compiler. Writing a switch-case from the start with guarantees this. FYI, some features in other languages try to bridge the abstraction/optimization gap. Scala has the @switch annotation, requiring compilation to a JVM tableswitch or lookupswitch, or else failure to compile. Commented Feb 5, 2015 at 23:10
  • @supercat, you describe a O(log n) algorithm. switch-case (when compiled to a lookup table) is O(1) Commented Feb 5, 2015 at 23:11
5

Compilers for most of the low end processors(Mostly Used in Embedded Systems) compiler do not always generate jump table for switch case.

If the case variables are in sequence (e.g 1,2,3,4....) then jump table implementation of switch case is preferred by compiler ,but for random sequence of case variable(e.g. 12,344,565,1,5...) compiler generates same code as generated in case of if-else code.

Sometimes,due to this developers land into trouble when adding a random case variable into already OK code may change the whole implementation of the that section of code which can result major change in code execution timing and code size. These are most concerning point to a embedded developer.

5
  • 2
    @EJP why is this untrue? I has faced this issue on one of my projects. I am not saying this is the behavior of all compilers.Please explain me your point if am missing something.
    – Vagish
    Commented Feb 5, 2015 at 9:46
  • My point is that when you use switch statement in resource critical systems you should be aware of what your compiler is doing with your code.
    – Vagish
    Commented Feb 5, 2015 at 9:50
  • You should say “If … compiler generates …” if you actually mean “If … compiler may generate …” or “I encountered one compiler which generates …if …”
    – Holger
    Commented Feb 5, 2015 at 13:57
  • @Holger, have you considered to rewrite your comment using switch? ;)
    – jmster
    Commented Feb 5, 2015 at 20:09
  • Damn typo it should be: You shouldn’t say “If … compiler generates …” if you actually mean “If … compiler may generate …” or “I encountered one compiler which generates …if …”
    – Holger
    Commented Feb 6, 2015 at 9:43
2

An if else is better than a switch case in the event that you have few choices, with deep decision trees, or need to use non-specific decision making,

ie. it's easy to implement an if statement that checks whether an int is greater than 0, which is more difficult to build into a switch statement. This is the type of logic that is best implemented using if statements.

If you have a flat, very broad, but specific condition dependent decision table, then a switch case is better. For example, you want specific things to happen if when a value is either 1, 2, 3, 4...etc to 10, it will be easier and saner to use a switch case.

In the end, modern compilers will change it to whatever is most efficient computationally, but how you built it will affect functionality, and supportability once you build it.

1

From the question of comparing a switch with an if..then..else construct, ~I assume that you are only cocnerned with a situation where a single test is required and the outcome depends on the answer (eg if x == ?? then ...). It is always better to use a switch in this case since: a) you cannnot introduce an erroneous condition part way down the chain of tests. b) the test is only undertaken once.

Not the answer you're looking for? Browse other questions tagged or ask your own question.