Java Optimizing Switch Statements
by Zander Kidd
The Java compiler has two different ways it can compile your switch statements.
Fast – tableswitch
switch(num) {
case 1: func2();
case 2: funct2();
case 3: funct3();
}
If it sees that your case values are all close to each other then it optimizes it such that either:
- The value does not lie within the range: jump to default
- The value is within the range: calculate correct offset and directly jump to it
This always takes O(1) time since the value does not need to be compared to every possible case; or any of the cases for that mater.
Slow – lookupswitch
switch(num) {
case 1: funct1();
case 42: funct2();
case 9001: funct3();
}
If your values aren’t close to each other then the compiler compiles the switch into a similar manner as an if statement and each value is compared to the cases one after another until the result is found.
This takes O(n) time since a switch that goes to default will have had to compare itself with every single case.
Forcing a compile to tableswitch
So tableswitch is obviously better when you’ve got many cases in your switch but that doesn’t mean the Java compiler will always use it.
If you want to check which was the compiler compiled it run:
javap <class file> > out.txt
and search out.txt for tableswitch or lookupswitch.
If it used lookupswitch where you think tableswitch would be better then you have two options:
- Add extra empty cases into the switch to make the compiler think the cases are all in a close range, note that you don’t have to add every case. The Java compiler automatically adds missing empty cases and uses tableswitch if just most values within the range are being used
- Split the switch statement into multiple switch statements so each group of statements fall within a range