PMD告诉我
少于3个分支的开关效率低下,请使用if语句代替。
为什么会这样呢?为什么是3?它们如何定义效率?
发布于 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
虽然与使用if语句相比,使用开关时效率提高不大,但在大多数情况下,这些增益是微不足道的。任何值得其salt的源代码扫描器都会认识到,微优化是代码清晰度的次要部分。
他们说,如果切换非常短,则if语句既易于读取,所占用的代码行也比switch语句少。
来自PMD网站
TooFewBranchesForASwitchStatement:开关语句缩进用于支持复杂的分支行为。只在少数情况下使用开关是不明智的,因为开关并不像随后的语句那样容易理解。在这些情况下,使用In these语句来增加代码的可读性。
发布于 2012-05-05 04:06:52
为什么会这样呢?
当JIT编译器(最终)将代码编译成本机代码时,会使用不同的指令序列。开关由执行间接分支的一系列本机指令实现。(该序列通常从一个表加载一个地址,然后分支到该地址。)if / else是作为计算条件(可能是比较指令)的指令实现的,后面是条件分支指令。
为什么是3?
这是一个经验性的观察,我假设是基于分析生成的本机代码指令和/或基准。(也可能不是。要确定,您需要问PMD规则的作者,他们是如何得出这个数字的。
它们如何定义效率?
执行指令所需的时间。
我个人会反对这条规则..。或者更准确地说是信息。我认为应该说,if / else语句比2种情况下的开关更简单、更易读。效率问题是次要的,而且可能与此无关。
https://stackoverflow.com/questions/10458719
复制相似问题