55

I'd like to know what the worst-case runtime complexity of a switch statement is, assuming you have n cases.

I always assumed it was O(n). I don't know if compilers do anything clever, though. If the answer is implementation-specific, I'd like to know for the following languages:

  • Java
  • C/C++
  • C#
  • PHP
  • Javascript
Fragsworth
  • 33,919
  • 27
  • 84
  • 97
  • 12
    The answer is not only language specific, not even compiler specific. It depends on the actual code. Some switch statements are turned into jump tables by some compilers. – Sven Marnach Dec 14 '10 at 18:37
  • 3
    At the other extreme, the values may cause other functions to be called. In Ruby, for example, values are checked using the `===` operator, which can do anything. One common use of this is regular expressions, which (in certain cases) can be very expensive -- so the cost of the switch is dominated by the values themselves, not by how many there are. – Ken Dec 14 '10 at 18:49
  • Is there any situation where it could be *greater* than O(n) (for *n* cases in the switch)? – FrustratedWithFormsDesigner Dec 14 '10 at 19:04
  • @Frustrated Gosh, I hope not. – Josh Lee Dec 14 '10 at 19:28
  • @jleedev: maybe as some sort of evil anti-optimization compiler option... that would be a nasty April Fool's prank ;) – FrustratedWithFormsDesigner Dec 14 '10 at 19:31

5 Answers5

48

It is at worst O(n). Sometimes (and this is language and compiler dependent), it translates to a jump table lookup (for "nice" switches that don't have too large a case range). Then that is O(1).

If the compiler wants to be funky, I can think of ways that the complexity can be implemented to be anything in between (e.g. perform binary search on the cases, for logn). But in practice, you're going to get eiher linear time or constant time.

lijie
  • 4,811
  • 22
  • 26
20

The big-O complexity of a switch statement is not really the important point. Big-O notation refers to the performance as n increases towards infinity. If you have a switch statement big enough that the asymptotic performance is an issue then it is too big and should be refactored.

Apart from the readability issue, in Java and C# I think you would soon hit some internal limits for the maximum size of a single method.

For relatively small switch statements that are called often it would probably be more informative to measure the actual performance of the switch statement against other approaches that you could use instead. This measurement could be made by repeatedly performing the operation in a loop.

For larger switch statements I'd suggest refactoring to use a dictionary or similar data structure that has approximately O(1) performance even has n gets very large and it won't run into problems with the limited method size.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 14
    If a 10-case switch statement is called frequently enough, would it not make sense to try to understand how it works internally? – Fragsworth Dec 14 '10 at 18:42
  • I completely agree. When you get upwards of 10 cases you rapidly lose readability and simplicity. There's usually a better, clearer way to go about things. – Gordon Gustafson Dec 14 '10 at 18:42
  • 4
    @Fragsworth yes, you should definitely try to understand how it works internally. But the only thing Big-O tells you is how fast it will be with LOTS of cases, say 100+. Mark's point is that there are far better ways to analyze the switch statements' internals without looking at its big-O, like how the compiler optimizes it and how it will compare with using other methods like a look-up table. – Gordon Gustafson Dec 14 '10 at 18:44
  • 7
    If the answer is O(n), then I would know that I could optimize by putting more frequent cases first; if the answer is O(1) then I would know that this does not help. Therefore knowing the runtime complexity does elucidate at least a few things. – Fragsworth Dec 14 '10 at 18:49
  • 5
    @Fragsworth: it could be O(n) but not using textual order. it might take a hash of the value and linearly compare to hashes of the constants, or it might reorder the code to optimize some other things (like register allocation, or stack usage), wreck your ordering, or many other things – Javier Dec 14 '10 at 18:55
  • 2
    @Fragsworth: Another problem with considering the O(n) notation is that the compiler might do some clever optimization for a switch statements that has very few entries, but use a different (worse) strategy for more entries. Then O(n) notation will tell you the asymptotic performance of the **worse** strategy, which isn't at all what you want to know. You should stop thinking in terms of big-O and instead think about the **actual** performance on real data. Besides, when you are making micro-optimizations like this you should **profile**. – Mark Byers Dec 15 '10 at 20:14
  • This is basically saying "Although I don't know the answer to the question, you should not be asking it in the first place and should not even care", a typical example of toxic and unhelpful (if not useless) stackoverflow answers. – Zhe Dec 10 '21 at 01:50
11

C++ compilers can turn switch statements into a jump table (i.e. construct an array of jump offsets, then take the value and use it as an index into the table). This is O(1).

The C# compiler uses a similar approach, except that it can assemble a hash table.

Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
10

C with gcc compiler has O(1) for tight range (jump table) or at worst O(log N) for loose range (binary search).

Smit Johnth
  • 2,281
  • 1
  • 22
  • 16
5

The worst case might be O(n), but at least for languages like C/C++, Java and C# where the cases are compile-time constants, a jump table can often be used (and quite often is used) to get the complexity to O(1).

I don't know if the more dynamic languages like PHP or Javascript try to set up jump tables or not.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • For php, case expressions need not be constant; `switch(true) { case expr: doSomething(); }` is valid, even if expr is not constant. That is, if I remember correctly. So jump tables would be unlikely for something like that. – user314104 Mar 13 '12 at 03:17