为什么在 Java 7 中,Switch 语句比其他字符串的语句快?
2022-09-02 19:46:46
在 Java 7 中,对象可以位于语句的表达式中。有人可以从官方文件中解释以下声明吗?string
switch
Java 编译器从使用 String 对象的 switch 语句生成字节码通常比从链接的 if-then-else 语句生成的字节码更有效。
在 Java 7 中,对象可以位于语句的表达式中。有人可以从官方文件中解释以下声明吗?string
switch
Java 编译器从使用 String 对象的 switch 语句生成字节码通常比从链接的 if-then-else 语句生成的字节码更有效。
一个类有两个版本,例如
跟:if-then-else
public class IfThenElseClass {
public static void main(String[] args) {
String str = "C";
if ("A".equals(str)) {
} else if ("B".equals(str)) {
} else if ("C".equals(str)) {
}
}
}
跟:switch
public class SwitchClass {
public static void main(String[] args) {
String str = "C";
switch (str) {
case "A":
break;
case "B":
break;
case "C":
break;
}
}
}
让我们来看看字节码。获取版本的字节码:if-then-else
Compiled from "CompileSwitch.java"
public class CompileSwitch {
public CompileSwitch();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String C
2: astore_1
3: ldc #18 // String A
5: aload_1
6: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
9: ifne 28
12: ldc #26 // String B
14: aload_1
15: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
18: ifne 28
21: ldc #16 // String C
23: aload_1
24: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
27: pop
28: return
}
获取版本的字节码:switch
Compiled from "CompileSwitch.java"
public class CompileSwitch {
public CompileSwitch();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String C
2: astore_1
3: aload_1
4: dup
5: astore_2
6: invokevirtual #18 // Method java/lang/String.hashCode:()I
9: lookupswitch { // 3
65: 44
66: 56
67: 68
default: 77
}
44: aload_2
45: ldc #24 // String A
47: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
50: ifne 77
53: goto 77
56: aload_2
57: ldc #30 // String B
59: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
62: ifne 77
65: goto 77
68: aload_2
69: ldc #16 // String C
71: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
74: ifne 77
77: return
}
在第一个版本中,通过为每个条件调用方法来比较字符串,直到找到它。equals
在第二个版本中,首先获得字符串。然后将其与每个 的值进行比较。请参阅。如果这些值中的任何一个重复,则恰好运行 .否则,请调用绑定的案例的方法。这比仅调用该方法要快得多。hashCode
hashCode
case
lookupswitch
case
equals
equals
switch
on 字符串可以更快,原因与字符串哈希集中的查找可能比字符串列表中的查找更快的原因相同:您可以在 中而不是在 中进行查找,其中字符串的数量。O(1)
O(N)
N
回想一下,这比语句链更有效,因为它是计算的跳转:代码中的偏移量是根据值计算的,然后执行跳转到该偏移量。Java可以使用类似于哈希映射和哈希集中使用的机制在字符串上拉动类似的技巧。switch
if-then-else