效率:将语句切换到 if 语句

2022-09-01 11:44:00

PMD告诉我

分支少于 3 个的交换机效率低下,请改用 if 语句。

为什么?为什么是 3?他们如何定义效率?


答案 1

因为语句是使用两个特殊的 JVM 指令编译的,即 和 。它们在处理大量案例时很有用,但是当您只有几个分支时,它们会导致开销。switchlookupswitchtableswitch

相反,语句被编译成典型的...链速度更快,但在长链分支中使用时需要更多的比较。if/elsejejne

您可以通过查看字节代码来查看差异,无论如何,我不会担心这些问题,如果任何事情可能成为问题,那么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

答案 2

尽管与使用 if 语句相比,使用开关时效率提升很小,但在大多数情况下,这些增益可以忽略不计。任何值得一试的源代码扫描器都会认识到,微优化是代码清晰度的次要因素。

他们说,如果开关明显较短,则 if 语句比 switch 语句更易于阅读,并且占用的代码行数更少。

来自 PMD 网站

TooFewBranchesForASwitchStatement:Switch 语句被缩进以用于支持复杂的分支行为。仅在少数情况下使用开关是不明智的,因为开关不像if-then语句那样容易理解。在这些情况下,使用 theif-then 语句来提高代码的可读性。


推荐