Is using one the switch statement better then using multiple if statements?

Started by
20 comments, last by frob 7 years, 9 months ago

I am currently learning C++ and I was just wondering if using the switch statement is better and/or a better and more efficient way of using multiple if statements? Is there advantages to using multiple if statements? If there is what are they?

Are switch statements good in game development?

I am just curious as I am learning C++ and I want to get my knowledge banks stored up :P

Advertisement

Better how? Switch-statements can be way faster then if/else-chains, specifically if there are many items to check for.

The compiler is free to optimize the switch-statement as he pleases. For a small number of items, the compiler might just produce an if/else-chain in the background. However, if you have like say 20-30 items, then the switch can ie. be converted to a table-lookup, which is way cheaper than having to check perform up to 30 if-conditions.

A reason for using multiple if/elses is mostly if you cannot use a switch, ie. if you are comparing strings, or other non-literal types.

But keep in mind that unless you are calling that block of code many many times per frame, this won't matter at all. At this level, always prefer code clearity over performance. So if you are asking if switch-statements are better in this regard: Largely depends. For many items, switch can easily be more readable, and safer (since you cannot accidentially check for the same item multiple times).

However for just 1 or two items, if/else tends to be more readeably, if not for being shorter. Consider this:


if(x == 2)
    foo();
else
    bar();

// switch is moar awesome!

switch(x)
{
case 2:
    foo();
    break;
default:
    bar();
    break;
}

So to sum up, both have their uses. Worry only about efficiency if you know you are working on performance critical code and/or if you did proper benchmarking. Otherwise, choose whichever is more appropriate to the situation in terms of readability and clearity - just don't got around and throw switch-statements at every single if-statement and you should be fine :)

Better how? Switch-statements can be way faster then if/else-chains, specifically if there are many items to check for.

The compiler is free to optimize the switch-statement as he pleases. For a small number of items, the compiler might just produce an if/else-chain in the background. However, if you have like say 20-30 items, then the switch can ie. be converted to a table-lookup, which is way cheaper than having to check perform up to 30 if-conditions.

A reason for using multiple if/elses is mostly if you cannot use a switch, ie. if you are comparing strings, or other non-literal types.

But keep in mind that unless you are calling that block of code many many times per frame, this won't matter at all. At this level, always prefer code clearity over performance. So if you are asking if switch-statements are better in this regard: Largely depends. For many items, switch can easily be more readable, and safer (since you cannot accidentially check for the same item multiple times).

However for just 1 or two items, if/else tends to be more readeably, if not for being shorter. Consider this:


if(x == 2)
    foo();
else
    bar();

// switch is moar awesome!

switch(x)
{
case 2:
    foo();
    break;
default:
    bar();
    break;
}

So to sum up, both have their uses. Worry only about efficiency if you know you are working on performance critical code and/or if you did proper benchmarking. Otherwise, choose whichever is more appropriate to the situation in terms of readability and clearity - just don't got around and throw switch-statements at every single if-statement and you should be fine :)

Thanks, that gives me a lot better understanding of it! :)

Better how? Switch-statements can be way faster then if/else-chains, specifically if there are many items to check for.

The compiler is free to optimize the switch-statement as he pleases.


The compiler is free to optimize almost anything as it pleases. There is absolutely nothing whatsoever that specially allows a switch statement to be better optimized than if-statements.

Older compilers _wouldn't_ optimize the if-statements as well, but that was a technology limitation. The switch statement is easier to recognize as what it is, while slightly more clever analysis is required to determine that a series of if-statements can be similarly optimized.

Modern compiles are not so stupid, however. Example: https://godbolt.org/g/i5NBKH Note that foo() and bar() are both compiled into jump tables despite one using a switch statement and the other an if-statement chain.

Sean Middleditch – Game Systems Engineer – Join my team!

Modern compiles are not so stupid, however. Example: https://godbolt.org/g/i5NBKH Note that foo() and bar() are both compiled into jump tables despite one using a switch statement and the other an if-statement chain.

Doesn't seem to be the case for GCC and MSVC.

I am currently learning C++ and I was just wondering if using the switch statement is better and/or a better and more efficient way of using multiple if statements? Is there advantages to using multiple if statements? If there is what are they?

Are switch statements good in game development?

I am just curious as I am learning C++ and I want to get my knowledge banks stored up :P

There is just one goal you should aim for all the time, in all languages: Be as clear and simple to understand as you can.

If the code is easier to understand as a switch, use a switch. If it is easier to understand as a sequence of if statements, use if statements.

Even if both variants effectively perform the same computation, the message you're giving to a reader of your code is completely different. A switch says "there are N separate cases to consider", a sequence of if statements says "do the M following sequential steps".

Use whatever fits best in explaining to the reader what the code is doing.

Better how? Switch-statements can be way faster then if/else-chains, specifically if there are many items to check for.

The compiler is free to optimize the switch-statement as he pleases.


The compiler is free to optimize almost anything as it pleases. There is absolutely nothing whatsoever that specially allows a switch statement to be better optimized than if-statements.

Older compilers _wouldn't_ optimize the if-statements as well, but that was a technology limitation. The switch statement is easier to recognize as what it is, while slightly more clever analysis is required to determine that a series of if-statements can be similarly optimized.

Modern compiles are not so stupid, however. Example: https://godbolt.org/g/i5NBKH Note that foo() and bar() are both compiled into jump tables despite one using a switch statement and the other an if-statement chain.

Thats neat, didn't know that, yet as been said MSVC isn't that clever (thats where my assumption originally came from).

There appears to be one case for a switch being faster/less assembly even on clang though, that is if you can tell the compiler that the default-case will never be hit (by replacing return 0 with __builtin_assume(0)). This gets rid of four lines of assembly in your example. Doing the same with if/else-chains doesn't work, and so I quess if you are working on a real tight loop that switches on a value within a known range (like an enum class), than this can still be a point for switch (unless there is a way to get clang to emit the same assembly for the if/else-chain).

Unless it's in a performance-critical part of the code, just use whichever makes the code clearer and move on. Otherwise it's actually really difficult to give a generalized answer to such a broadly-scoped question these days.

On modern hardware, with sophisticated branch prediction, the question of which approach is faster is probably not so clear-cut, and overly simplistic approaches (such as counting the number of asm instructions) could give misleading results. If it's absolutely performance-critical you really should be coding up both, and doing proper profiling under a representative real-world workload.

If you're debating between using if or switch to avoid doing a calculation (or other work), you should also be considering whether the cost of the calculation is going to be less or more than the cost of the branch.

Different hardware is different. What's faster on PC hardware may not be faster on mobile hardware, and vice-versa.

Are you going to blow cache? Is it going to scale across multiple threads? How well will it pipeline? These can all be more important than micro-optimizing at the individual assembly instruction level.

Bottom line is that it's not the 1970s, 1980s, 1990s or even 2000s any more, and you absolutely do need to consider the performance characteristics of your target hardware as well as those of your code.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Better how? Switch-statements can be way faster then if/else-chains, specifically if there are many items to check for.

The compiler is free to optimize the switch-statement as he pleases. For a small number of items, the compiler might just produce an if/else-chain in the background. However, if you have like say 20-30 items, then the switch can ie. be converted to a table-lookup, which is way cheaper than having to check perform up to 30 if-conditions.

A reason for using multiple if/elses is mostly if you cannot use a switch, ie. if you are comparing strings, or other non-literal types.

First, you misslead the readers on what switch is. Since switch is named so improper, switch is not a switch, unless there is break keyword instruction in every sub-block of condition .
What switch does is that it evaluates all conditions in their order and executes their subblock if they are true. Logicily switch is equal to this

{// the escape block

if (A){}

if(B){}

if (C){}

{} // the default:

}

If you are sure that A and B and C will always be exclusive by being true, break will save you of only their conditional checks. You can omit default option, or place it in any roder, or you can break only in some code, not other, and create intent enigma hell for any reader of your code, as you have stressed readibility- there is no obvious readibility to switch (just a little hope there is break at every spot, or return, or continue).

Performance is a question of your run-time branching, performed instruction saves, navigating, not at all a question of wheather it was an if or a switch. But frankly, I cannot spot when and how switch can have outperformed proper conditionals in any way on any platform- and by my logic I conclude it cannot.

And to advice beginner programmers with switch for "readability", or "always use"- is a very bad service to them. I know we experienced programmers can even justify GoTo/Label, but doing so in production of your employer will get you fired. The paradox.

Performance is a question of your run-time branching, performed instruction saves, navigating, not at all a question of wheather it was an if or a switch. But frankly, I cannot spot when and how switch can have outperformed proper conditionals in any way on any platform- and by my logic I conclude it cannot.


The reason has already been covered in this very thread: switches are easy to convert to lookup tables in machine code. Conditional statements are less easy. So in a common case you will get better machine code generated for a switch than a if/else ladder. Some compilers are better at this than others.


Just because you can't imagine it doesn't mean it isn't true.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement