PMD告诉我
A switch with less than 3 branches is inefficient, use a if statement
instead.
为什么会这样?为什么是3?他们如何定义效率?
什么是PMD????
PMD扫描Java源代码,并查找潜在的问题,如可能的错误、死代码、次优代码、过复杂的表达式和重复代码。(将鼠标悬停在标签上)
它还应该扫描自己的语法。""less"应为"less"。:)
@jmort253更新了包含链接的问题
@"少"是合适的,"少"也是少的,"少"的内涵就足够了。cracked.com/blog/…
别把你的描述性语法强加于我,@mikemmahon!我喜欢我的语法,就像我喜欢我的冰川一样:旧的,冰冻的,移动得越慢越好。
强制性的"过早优化是万恶之源"等
不管效率如何,我都会使用最容易阅读的Java结构。如果必须进行优化,很可能不会出现在本节中。此外,如果必须具有性能,Java就是错误的语言。
因为switch语句是用lookupswitch和tableswitch两个特殊的JVM指令编译的。它们在处理许多情况时很有用,但是当您只有很少的分支时,它们会导致开销。
一个if/else语句被编译成典型的jejne语句。在长的分支链中使用时,速度更快但需要更多比较的链。
您可以通过查看字节代码来查看差异,在任何情况下,我都不会担心这些问题,如果有任何问题可能成为问题,那么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
杰克谢谢你。这是一个很好的答案。附带说明,您使用什么查看.class文件?
它是Eclipse的一个插件,如果我没记错的话,应该是这个插件:anderi.gmxhome.de/bytecode/index.html
@我相信你也可以使用javap。
众所周知,字节码是决定性能的唯一因素——JIT永远不会为了获得更好的性能而更改代码!另一个无用的性能优化
我想说这是一个非常差的优化器,它不能将2分支switch优化为if,因为if的性能更好。
哇,回答得很好+1
尽管与使用if语句相比,使用switch时效率提升较小,但在大多数情况下,这些提升可以忽略不计。任何值得一试的源代码扫描器都会认识到,微观优化是代码清晰性的次要因素。
他们说,如果switch非常短,那么if语句比switch语句更容易读取,占用的代码行也更少。
从PMD网站:
TooFewBranchesForASwitchStatement: Switch statements are indended to be used to support complex branching behaviour. Using a switch for only a few cases is ill-advised, since switches are not as easy to understand as if-then statements. In these cases use theif-then statement to increase code readability.
清晰度的重要性远远超过任何微观优化。毫无疑问。
好的是,它们在警告中声明"效率低下",但它们声明这与文档中的"可读性"有关。连贯性好。
Why is that?
当代码(最终)由JIT编译器编译为本机代码时,使用不同的指令序列。开关由执行间接分支的一系列本机指令实现。(序列通常从表中加载一个地址,然后分支到该地址。)if/else是一个实现为指令,用于评估条件(可能是比较指令),然后是条件分支指令。
Why 3?
我假设这是一个经验观察,基于分析生成的本地代码指令和/或基准测试。(或者可能不是。要绝对确定,您需要询问PMD规则的作者,他们是如何得出这个数字的。)
How do they define efficiency?
执行指令所用的时间。
我个人会反对这条规则…或者更准确地说是关于信息。我认为应该说一个if / else语句比一个包含两个事例的开关更简单、更易读。效率问题是次要的,可能无关紧要。
我认为这与开关和if/else的编译方式有关。
假设处理switch语句需要5次计算。假设一个if语句需要两个计算。您的交换机中少于3个选项将等于4个计算(在IFS中)和5个计算(在交换机中)。但是,在一个交换机中,开销保持不变,因此如果它有3个选择,那么将处理3*2的ifs,而对于交换机仍然是5个。
当看到数以百万计的计算时,收益是极其微不足道的。更重要的是"这是更好的方法"而不是任何可能影响你的事情。它只能在一个相当迭代中,在这个函数上循环数百万次。