How is String in switch statement more efficient than corresponding if-else statement?

14,473

Solution 1

Using a switch statement is faster than equals (but only noticeably when there are more than just a few strings) because it first uses the hashCode of the string that switch on to determine the subset of the strings that could possibly match. If more than one string in the case labels has the same hashCode, the JVM will perform sequential calls to equals and even if there is only one string in the case labels that a hashCode, the JVM needs to call equals to confirm that the string in the case label is really equal to the one in the switch expression.

The runtime performance of a switch on String objects is comparable to a lookup in a HashMap.

This piece of code:

public static void main(String[] args) {
    String s = "Bar";
    switch (s) {
    case "Foo":
        System.out.println("Foo match");
        break;
    case "Bar":
        System.out.println("Bar match");
        break;
    }
}

Is internally compiled to and executed like this piece of code:

(not literally, but if you decompile both pieces of code you see that the exact same sequence of actions occurs)

final static int FOO_HASHCODE = 70822; // "Foo".hashCode();
final static int BAR_HASHCODE = 66547; // "Bar".hashCode();

public static void main(String[] args) {
    String s = "Bar";
    switch (s.hashCode()) {
    case FOO_HASHCODE:
        if (s.equals("Foo"))
            System.out.println("Foo match");
        break;
    case BAR_HASHCODE:
        if (s.equals("Bar"))
            System.out.println("Bar match");
        break;
    }
}

Solution 2

In general, switch statements are better because they are (loosely speaking) O(1), while a chain of if-else is O(n)

Having n conditions could result in up to n comparisons using a chained if-else statements.

A switch statement can "jump" directly to the appropriate condition (like a map) or to the default case, making it O(1).

Solution 3

This is a bytecode fragment generated from example in the docs:

 INVOKEVIRTUAL java/lang/String.hashCode ()I
    LOOKUPSWITCH
      -2049557543: L2
      -1984635600: L3
      -1807319568: L4

using LOOKUPSWITCH has better perfomance compared to if-else logic

Share:
14,473
Aniket Thakur
Author by

Aniket Thakur

Hi there, I love to code and learn new things! I firmly believe that "It is your attitude rather than your aptitude that determines your altitude" and "Nothing is impossible if you give it your sincere try". My Blog - Open Source For Geeks You can also view - My Playstore Apps and My Git repositories / Gists Youtube channel Chrome Plugin All the Best! Stay in touch :) (LinkedIn Profile)

Updated on June 17, 2022

Comments

  • Aniket Thakur
    Aniket Thakur almost 2 years

    Java documentation says

    The Java compiler generates generally more efficient bytecode from switch statements that use String objects than from chained if-then-else statements.

    AFAIK even String in switch uses .equals() internally in a case sensitive manner. So what efficiency do they mean in this context. Faster compilation? Less bytecodes ? better performance?