switch Vs. if else

Started by
5 comments, last by Xai 15 years, 5 months ago
Is either if else or switch more efficent than the other? I know in my experience if else get rather confusing after more than three or four. So is there an unwritten rule on how many if elses you do before you change it to a switch or is it just whatever you feel comfortable with?
Advertisement
In some cases, a compiler can produce more efficient code from switch blocks. This is particularly the case when all of the constants are small-ish, mostly contiguous integers. I don't know of any situations in which if-else chains would be more efficient.

There is nothing syntactically ugly about a switch block with only two items.
So would you recommend switches whenever possible? And thanks for the super fast reply!
No, not always. I would recommend it in any case where the most reasonable interpretation of the function is a 1-to-1 mapping from an integer to a block of functionality.
Great thanks for the help!
Realistically, the difference between if/else chains and a switch statement [where an action can be interpreted in both forms] is pretty much just syntactic. If you're interested in arguments for why the switch statement could arguably be considered 'faster' than a sequence of if/else pairs is generally this: If the variable that you are 'switching' over has a very small domain of interest, and that it is dense with respect to the elements of interest [say, {1,2,3} as opposed to {1,12342,8587372}] then the statement can be resolved down to an array lookup, with the result of that array being the code segment that should be executed. This is referred to as a 'jump table', and means that there are really no checks for equality on a case-by-case basis, instead just treating the argument as an index into an array. Since a switch statement doesn't express things in terms of anything except equality, this works out just fine in many cases. In cases where the domain is not dense with interesting elements, it resolves down into a if/else chain.

But, compilers are clever these days, and there is plenty of work that has already been done with respect to recognizing in if/else chains the conditions that are interesting for optimization if they were instead represented as a switch statement [in short, if/else chains can also find themselves implemented as jump tables if they meet the requirements]. Switch statements are just trivially mapped to this form, which if/else chains may require some careful observation on the part of your compiler [which it really should be capable of doing].

In any case though, hand-converting your conditionals over from if/else chains into switch statement will only gain you a very tiny sliver of performance, if anything at all [I'd argue that it'll gain you straight out nothing in the vast majority of cases, but I'm sure some would disagree with me, so I'll at least put forward that it has a potential of only gaining you very little]. This conversion process though may very well make things more challenging to read, and less obvious in their interpretation, and thus result in an obfuscation of your code which damages maintainability. Maintainability is FAR more important than the quantum of performance that would be gained by making this transition.

Strive for readability in this situation, and use whatever conveys the solution to your problem most clearly.
Also, switches are more readable in the few types of cases they support, specially because they only support a certain type of case ... if you see a switch statement on variable x, then you know 100% the only thing determining what code gets run is variable x's current value, and that each block will list the values that can run it ... in if-else cases there is much more freedom to do stuff mixed in to the prime tests list:

if(x < 0)
...
else if(x < 100 && (currentHealth > maxHealth * 0.5)
...
else if(x < 200)
...
else
...

of course that's also assuming you don't take advantage of fall-through. I highly recommend that you put a comment above any switch that leverages fall-through, or at least in the place where the break would be:

case -1:
x = 0;
// fallthrough to next case
case 0:
lives -= 1;
// fallthrough to next case
default:
processLoop();

of course that was a bad example of when to use cases ... but you get the idea.

This topic is closed to new replies.

Advertisement