Java switch 语句中的字符串如何比相应的 if-else 语句更有效?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22110707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:39:14  来源:igfitidea点击:

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

javastringif-statementswitch-statement

提问by Aniket Thakur

Java documentationsays

Java 文档

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

Java 编译器从使用 String 对象的 switch 语句生成的字节码通常比从链式 if-then-else 语句生成的字节码更有效。

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?

AFAIK 甚至 String 在 switch.equals()中以区分大小写的方式在内部使用。那么它们在这种情况下意味着什么效率。更快的编译?更少的字节码?更好的性能?

采纳答案by Erwin Bolwidt

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 hashCodeof the string that switchon 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 equalsand even if there is only one string in the case labels that a hashCode, the JVM needs to call equalsto confirm that the string in the case label is really equal to the one in the switch expression.

使用 switch 语句比 equals 更快(但只有在有多个字符串时才明显),因为它首先使用hashCode该字符串的 的switch来确定可能匹配的字符串子集。如果 case 标签中有多个字符串具有相同的 hashCode,JVM 会依次调用equals,即使 case 标签中只有一个字符串是一个 hashCode,JVM 也需要调用equals以确认 case 中的字符串label 真的等于 switch 表达式中的那个。

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

在 String 对象上切换的运行时性能与在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;
    }
}

回答by Evgeniy Dorofeev

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

与 if-else 逻辑相比,使用 LOOKUPSWITCH 具有更好的性能

回答by Tyler

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

一般,开关语句是更好,因为它们是(严格意义上)O(1),而链if-elseISO(n)

Having nconditions could result in up to ncomparisons using a chained if-elsestatements.

n条件可能导致多达n使用链式比较if-else报表。

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

switch 语句可以直接“跳转”到适当的条件(如地图)或默认情况,使其O(1).