0

In the realm of performance which is consider more efficient?:

A small switch statement consisting of under 3 cases/below 3 cases? Or A small if chain consisting of under 3 conditions/below 3 conditions?

For example:

int x = 1;
switch (x) {
    case 1:
        //....do something
    case 2:
        //....do something
    case 3:
        //....do something
}

Or

int x = 1:
if (x == 1) {
    //....do something
}
else if (x == 2) {
    //....do something
}
else if (x == 3) {
    //....do something
}

Are both considered equally efficient? Or does one dominate the other via speed?

ty_c0der
  • 15
  • 5
  • 2
    Neither, the optimizer is likely to generate the same code regardless of what you write. So write the code in the way that's easiest to read, and let the optimizer do its job. – user3386109 Feb 15 '21 at 21:31
  • Even if there's a difference, it will be negligible for a small list. – Barmar Feb 15 '21 at 21:34
  • Interesting point because I continuously read that switch is faster that if but usually it pertains to large switch statements and if chains, has this changed in recent compiler versions? It seems many of the answers of questions of similarity are old. – ty_c0der Feb 15 '21 at 21:34
  • @Barmar what about in the area of something like brute-force/decryption? Would there be a difference at all? – ty_c0der Feb 15 '21 at 21:36
  • 1
    Measure and find out. – GManNickG Feb 15 '21 at 21:38
  • Let's say the difference is 1 microsecond. If you execute it a million times, it will add an entire second to the length of the process. If the process takes 10 minutes, the difference between 10:00 and 10:01 is negligible. – Barmar Feb 15 '21 at 21:41
  • @NickReed: I find myself disagreeing with the dupe because it looks like VS specific verses cross-platform to my eyes. – Joshua Feb 15 '21 at 21:47
  • Well, what if the process is 10 hours? I do see your point, I just want to be positive moving forward with other projects - If there is a case scenario where it could matter. – ty_c0der Feb 15 '21 at 21:47
  • It's easy for the compiler to recognize a `switch` and decide whether it would be faster as a jump table, a sequence of comparisons, or something else. However, recognizing that a chain of `if`s is really a `switch` and can be transformed to a jump table, hash, etc, is not as easy for the compiler, and it may miss that optimization in some cases where it would be desirable. So `switch` is likely to give you the best code in most cases. – Nate Eldredge Feb 15 '21 at 21:50
  • [Premature optimization is the root of all evil](http://c2.com/cgi/wiki?PrematureOptimization). Do whatever you feel is most natural and readable, and optimize it if it becomes a performance bottleneck. – Barmar Feb 15 '21 at 21:57
  • @ty_c0der If the process takes 10 hours and you add 1 second, it's even more negligible. – Barmar Feb 15 '21 at 21:58
  • What matters is the ratio of the time difference to the time taken by the loop that contains it. If the difference is 0.01%, then it means a 10 hour process will take an extra 3-4 minutes. Would you really notice? – Barmar Feb 15 '21 at 22:01

1 Answers1

-1

In theory, the switch statement is usually faster than an if/else ladder because a switch statement compiles to a jumptable when remotely possible to do so. My understanding is modern optimizers can do as well for that if-then-else ladder so in practice it won't be faster.

In the worst case, the switch statement will not be slower, so if in doubt, write the switch statement. Besides, it's easier to read and that's almost always worth it.

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • 1
    I disagree. There are more factors which can be taken into the consideration, caching of the code, number of branches, order of ifs etc etc. If switch/if ladder is executed frequently you need to benchmark as result sometimes are surprising. Sometimes switches can be 3-4 times slower than if-s and in another cases they can be 3-4 times faster. – 0___________ Feb 15 '21 at 22:01
  • @0___________ Agreed. also the optimization typically goes in the other direction. Small switches to small if-else ladders (gcc tends to do this more than clang), but I've never seen a compiler conjure up a jump table from an if-else ladder. – Petr Skocik Feb 15 '21 at 22:09
  • Am I the only one who has seen it? – Joshua Feb 15 '21 at 22:10
  • "compiles to a jumptable when remotely possible" sounds quite a strong guarantee. So does the statement about one always being not slower. Some reference would be nice. – ilkkachu Feb 15 '21 at 22:25
  • @ilkkachu: We're well past the point of trust the optimizer until proven otherwise at this time. – Joshua Feb 15 '21 at 22:27
  • 1
    @PSkocik, now that I tried, clang 3.8.1-24 from my Debian seemed to do just that. A simple 9-way if sequence (with mostly similar contents for each branch) compiled to an identical jump table as the equivalent switch. – ilkkachu Feb 15 '21 at 22:30
  • PS IMO Your answer is just your opinion without any empirical data. It can be treated as the comment but for sure not as the answer, as it does not answer anything and is only giving false and misleading information – 0___________ Feb 15 '21 at 22:32
  • 1
    https://godbolt.org/z/86xcno - modified dupe example – 0___________ Feb 15 '21 at 22:34
  • @Joshua, I'm sorry, I don't understand. How does trusting or not trusting the optimizer prove that a switch statement can never ever compile into anything that would be slower than the equivalent if sequence? Or indeed that switch would always compile to a jump table? (Of course you did hedge that with "when remotely possible", but that's just the same as saying "when the compiler thinks it's useful to do that".) Sure, for some particular compiler they could indeed always compile like that, but I didn't see any particular one mentioned. – ilkkachu Feb 15 '21 at 22:37
  • @ilkkachu stop using prehistoric compiler versions. You are 8 major upgrades behind – 0___________ Feb 15 '21 at 22:37
  • @0___________, I never said it was recent. And unless you think a newer clang would no longer be able to realize that switch and the if chain are the same thing, I don't think the version matters. – ilkkachu Feb 15 '21 at 22:42
  • 1
    @ilkkachu Oh boy ... It does. It does https://godbolt.org/z/6TPbzE. As I wrote - always test - do not share myths – 0___________ Feb 15 '21 at 22:44
  • @0___________, oh yes, if I cared about the _speed_ very much, I would test. I hardly do, though, and I wasn't saying a newer version wouldn't have improvements over an old one. The point was just that it generates what very much looks like a jump table for even the if sequence, and that appears to be the same in clang 3.8 and clang 10.0. (and no, I don't care to get 11 just to test that.) But yes, you're right, for some reason the newer version _is_ able to optimize the switch further than the if. – ilkkachu Feb 15 '21 at 22:59
  • So I don't understand what's the conclusion? It depends on the situation, so test? – ty_c0der Feb 15 '21 at 23:11
  • 1
    @ty_c0der if something matters in your code - always test. There is no other way. – 0___________ Feb 15 '21 at 23:16