Optimization – How Switch/Case is Handled to Avoid Comparisons to Case Values

optimizationswitch statement

I've read in multiple answers that switch/case avoids "unnecessary" comparisons, but I never learned this in college, and I'm a little stumped on how the program would figure out which case to jump to without doing a comparison.

Obviously, in the case of int switchVar=3; switch (switchVar) { case 0: ... case 1: ... case 2: ... case 3: ... case n: ... }, this would be pretty easy, as it could just create an array of pointers that point to the beginning of each case's code block, and it would simply do something along the lines of instructionPointer = switchJumpTable[switchVar];.

However, this breaks down if you were to do a switch/case on a string, e.g. char switchVar[]="North"; instructionPointer = jumpTable[switchVar]; where trying to access the "North" index of an array would cause an error (or if the compiler allowed this behind the scenes, I still don't see how it would avoid comparisons when converting the char array into an integer in order to access the array.)

I can think of one way to get around unnecessary comparisons, but it wouldn't be terribly efficient, so I'm sorta curious as to how this is actually done, as I can't imagine that compilers are using the method that I have in mind.

Best Answer

The answer varies Enormously by the individual compiler, but there are a few strategies that "could" be used.

The usual answer is a jump table. The case variable is looked up in a table containing all of the allowed values, and the program jumps to the address the table specifies.

Of course, that's a fine strategy on the flat address models used in older CPU's, but the cost of an indirect branch on the deep pipelines of modern CPU's is often an order of magnitude greater than a simple conditional branch, (which is in turn more expensive than no branch). indirect branching usually breaks the branch prediction logic on most CPU's that have it, and so the instructions after the branch cannot be prefetched until the lookup instruction has actually completed. A regular conditional branch can prefetch one side of the branch and have a decent chance of 'guessing right'.

And so this optimization is rarely taken on compilers that target those CPU's, and instead the case statement is compiled as a tree of nested conditional branches.

Related Topic