为什么在Java7中,switch语句比if-else语句更快?
在Java7中,为什么在Java7中,switch语句比if-else语句更快?,java,if-statement,switch-statement,java-7,Java,If Statement,Switch Statement,Java 7,在Java7中,string对象可以是switch语句的表达式。有人能解释一下下面的陈述吗 Java编译器从使用字符串对象的switch语句生成的字节码通常比从链式if-then-else语句生成的字节码效率更高 它的效率更高,比如: switch(yourString) { case "text1": // your code break; case "text2": // etc. } 比记者: if (yourString.
string
对象可以是switch
语句的表达式。有人能解释一下下面的陈述吗
Java编译器从使用字符串对象的switch语句生成的字节码通常比从链式if-then-else语句生成的字节码效率更高
它的效率更高,比如:
switch(yourString) {
case "text1":
// your code
break;
case "text2":
// etc.
}
比记者:
if (yourString.equals("text1")) {
// your code
} else if (yourString.equals("text2")) {
// etc.
}
我猜这意味着什么,或者我理解的是,使用string从switch语句创建的字节码(编译java类时)比使用string从if-else语句创建的字节码更快、更高效。两者都可以做同样的工作,位切换显然更有效
switch (str) {
case "A":
// do something
break;
case "B":
// do something
break;
default:
//do something
break;
}
比
if(str.equals("A")) {
//do something
} else if(str-equals("B")) {
//do something
} else {
//do something
}
字符串上的
开关
可以更快,原因与在字符串哈希集中查找可能比在字符串列表中查找快的原因相同:您可以在O(1)
中进行查找,而不是在O(N)
中进行查找,其中N
是字符串数
回想一下,switch
比一连串的if-then-else
语句更有效,因为它是一个计算出的跳转:代码中的偏移量是基于该值计算的,然后执行到该偏移量的跳转。Java可以使用类似于散列映射和散列集的机制在字符串上使用类似的技巧。Java代码
一个类有两个版本,例如
使用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)) {
}
}
}
使用开关
:
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
}
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
。请参阅案例
。如果这些值中有任何一个仅在运行查找开关
案例的代码时才会重复。否则,调用绑定案例的
方法。这比只调用equals
方法要快得多equals