发布于 2012-05-05 04:06:48
因为switch语句是用两个特殊的JVM指令编译的,即lookupswitch和tableswitch。在许多情况下,它们都很有用,但是当您只有很少的分支时,它们会导致开销。
相反,if/else语句被编译成典型的je jne ..。链是更快,但需要更多的比较,当使用在一个长的分支链。
您可以通过查看字节代码来看出不同之处,在任何情况下我都不会担心这些问题,如果任何事情都可能成为问题,那么JIT就会解决它。
实际例子:
switch (i)
{
case 1: return "Foo";
case 2: return "Baz";
case 3: return "Bar";
default: return null;
}汇编成:
L0
LINENUMBER 21 L0
ILOAD 1
TABLESWITCH
1: L1
2: L2
3: L3
default: L4
L1
LINENUMBER 23 L1
FRAME SAME
LDC "Foo"
ARETURN
L2
LINENUMBER 24 L2
FRAME SAME
LDC "Baz"
ARETURN
L3
LINENUMBER 25 L3
FRAME SAME
LDC "Bar"
ARETURN
L4
LINENUMBER 26 L4
FRAME SAME
ACONST_NULL
ARETURN而
if (i == 1)
return "Foo";
else if (i == 2)
return "Baz";
else if (i == 3)
return "Bar";
else
return null;被编译成
L0
LINENUMBER 21 L0
ILOAD 1
ICONST_1
IF_ICMPNE L1
L2
LINENUMBER 22 L2
LDC "Foo"
ARETURN
L1
LINENUMBER 23 L1
FRAME SAME
ILOAD 1
ICONST_2
IF_ICMPNE L3
L4
LINENUMBER 24 L4
LDC "Baz"
ARETURN
L3
LINENUMBER 25 L3
FRAME SAME
ILOAD 1
ICONST_3
IF_ICMPNE L5
L6
LINENUMBER 26 L6
LDC "Bar"
ARETURN
L5
LINENUMBER 28 L5
FRAME SAME
ACONST_NULL
ARETURN发布于 2012-05-05 04:04:08
发布于 2012-05-05 04:06:52
为什么会这样呢?
当JIT编译器(最终)将代码编译成本机代码时,会使用不同的指令序列。开关由执行间接分支的一系列本机指令实现。(该序列通常从一个表加载一个地址,然后分支到该地址。)if / else是作为计算条件(可能是比较指令)的指令实现的,后面是条件分支指令。
为什么是3?
这是一个经验性的观察,我假设是基于分析生成的本机代码指令和/或基准。(也可能不是。要确定,您需要问PMD规则的作者,他们是如何得出这个数字的。
它们如何定义效率?
执行指令所需的时间。
我个人会反对这条规则..。或者更准确地说是信息。我认为应该说,if / else语句比2种情况下的开关更简单、更易读。效率问题是次要的,而且可能与此无关。
https://stackoverflow.com/questions/10458719
复制相似问题