我在Google上没有找到关于此比较的简洁答案,而且我也不想浪费时间进行自己的评估,因此我想先问一下。
我相当确定使用枚举的 switch 语句会比 if-then-else 语句执行得更快,不过是否有明显的差异则是另一个问题。
有人能为我解答一下吗?
谢谢大家的快速回复,我将记住这点以备将来的项目使用。
我在Google上没有找到关于此比较的简洁答案,而且我也不想浪费时间进行自己的评估,因此我想先问一下。
我相当确定使用枚举的 switch 语句会比 if-then-else 语句执行得更快,不过是否有明显的差异则是另一个问题。
有人能为我解答一下吗?
谢谢大家的快速回复,我将记住这点以备将来的项目使用。
没错,因为通常情况下,switch语句比if/else链的执行速度更快。
虽然生成的字节码并不总是性能比较的最终依据,但你可以检查它以获得更好的想法。
例如,这段代码:
class A {
enum N { ONE, TWO, THREE }
void testSwitch( N e ) {
switch( e ) {
case ONE : x(); break;
case TWO : x(); break;
case THREE : x(); break;
}
}
void testIf( Enum e ) {
if( e == N.ONE ) { x(); }
else if( e == N.TWO ) { x(); }
else if( e == N.THREE ) { x(); }
}
void x(){}
}
生成以下内容:
Compiled from "A.java"
class A extends java.lang.Object{
A();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
void testSwitch(A$N);
Code:
0: getstatic #2; //Field A$1.$SwitchMap$A$N:[I
3: aload_1
4: invokevirtual #3; //Method A$N.ordinal:()I
7: iaload
8: tableswitch{ //1 to 3
1: 36;
2: 43;
3: 50;
default: 54 }
36: aload_0
37: invokevirtual #4; //Method x:()V
40: goto 54
43: aload_0
44: invokevirtual #4; //Method x:()V
47: goto 54
50: aload_0
51: invokevirtual #4; //Method x:()V
54: return
void testIf(java.lang.Enum);
Code:
0: aload_1
1: getstatic #5; //Field A$N.ONE:LA$N;
4: if_acmpne 14
7: aload_0
8: invokevirtual #4; //Method x:()V
11: goto 39
14: aload_1
15: getstatic #6; //Field A$N.TWO:LA$N;
18: if_acmpne 28
21: aload_0
22: invokevirtual #4; //Method x:()V
25: goto 39
28: aload_1
29: getstatic #7; //Field A$N.THREE:LA$N;
32: if_acmpne 39
35: aload_0
36: invokevirtual #4; //Method x:()V
39: return
void x();
Code:
0: return
}
两种方法看起来都相当快。
因此,选择更易于维护的方法。
只需坚持编写最易读和理解的代码即可,我相信在寻找答案时已经失去了所有的性能优化所获得的时间。像这样的微小优化很少有价值,往往会导致代码比必要的更复杂。
我不确定哪个更快,但我猜两者都非常快。
我的考虑是,使用枚举和switch语句比使用多重if/else代码块更易读。
但要注意不要漏掉break语句!
是的,switch 语句通常比等效的 if / else 语句块执行得更快,因为编译器可以执行更多优化(通常,switch 块会被编译成分支表,而这在条件块中几乎不可能实现)。
我认为它们都更易读和更易维护(除非使用 fall-through cases,我建议不要使用!)
至于是否明显更快,这取决于您定义的“明显”程度。除非您追求某些非常特定的东西,否则您很可能根本不会注意到它,但我仍然会以可读性优势为主来做这件事(将速度优势视为奖励!)
对于这个问题,我的答案与通常的问题一样,即语言结构X是否比语言结构Y快:没有普遍的答案!
对于某些语言实现,例如Oracle(正式的Sun)基于Hotspot编译器的JVM,或IBM JDK在Z平台上,或OpenJDK在Linux上等,可能只有特定的答案。
因此,回答您的问题的唯一方法是进行适当的基准测试。要注意微基准测试,它们往往更容易出错而不是正确的,例如,请参见如何不编写微基准测试。如果您仍然想了解,请使用框架,其中描述在此。
因此,我建议根据上下文中的适用性和可读性选择语言特性。
无论如何,在可读性和可维护性方面,switch比if-else链更好,因此如果可能的话,请使用它们。
enum.ordinal() * sizeOfCase
)。 - OrangeDog