jit是否优化了分支太少的switch语句?

时间:2012-09-12 11:28:52

标签: java switch-statement jit

最近我碰到了静态代码分析工具(PMD)抱怨switch语句分支太少的情况。它建议把它变成一个if语句,我不想​​做,因为我知道很快会添加更多案例。但我想知道javac是否执行了这样的优化。我使用JAD反编译代码,但它仍然显示了一个开关。这可能是JIT优化的运行时吗?

更新:请不要被我的问题背景误导。我不是在询问PMD,我不是在询问是否需要微优化等等。问题显然只有这个:当前(Oracle 1.6.x)JVM实现是否包含一个处理交换机的JIT很少有分支机构。

4 个答案:

答案 0 :(得分:2)

确定JIT编译器如何优化switch语句的方法是:

  • 阅读JIT编译器源代码(OpenJDK 6和7是开源的)或
  • 使用开关运行JVM,该开关告诉它将文件中感兴趣的类的JIT编译代码转储。

请注意,与所有与性能和优化相关的问题一样,答案取决于硬件平台和JVM供应商和版本。

参考:Disassemble Java JIT compiled native bytecode


如果这个问题“只是空闲的好奇心”,那就这样吧。

但是,还应该指出,出于性能原因重写代码以使用switchif可能是一个坏主意和/或浪费时间。

  • 这可能是浪费时间,因为原始版本和手动优化版本之间的时间差异(如果有的话)可能是微不足道的。

  • 这是一个坏主意,因为您的优化可能仅对特定硬件和JVM组合有帮助。在其他方面,它可能没有效果......甚至是反优化。

简而言之,即使你知道JIT优化器如何处理这个问题,你也许不应该在编程中考虑它。

(当然例外是当你有一个真正可测量的性能问题,并且分析指向(比方说)一个3分支switch作为瓶颈之一。)

答案 1 :(得分:1)

如果你在调试模式下编译它,通常在你反编译它时,你仍然可以得到开关。否则,任何调试尝试都会遗漏某些信息,例如行号和原始指令流 因此,您可以尝试在生产模式下进行编译,看看反编译结果是什么。

然而,switch语句,特别是如果预计会增长,通常被认为是代码气味,应该被评估为重构的良好候选者。

答案 2 :(得分:1)

至于你澄清问题是什么之后。

由于这对硬件和JVM造成如此强烈的影响(使用Java商标的JVM可能由Oracle以外的公司开发,只要它们遵守JVM规范).Id说唯一有效的方法是进行速度测试

剪出一大块代码,将其锁定在循环中进行大量重复,检查循环执行前后的时间。重复两种解决方案(切换和if)

这可能看似简单和愚蠢,但它确实有效,并且比反编译,读取字节码和内存转储等快得多。


您必须记住,Java实际上使用的是虚拟机和字节码。我很确定这一切都得到了处理和优化。我们正在使用高级语言来避免您要求的微观管理和优化

更一般地说,我认为你试图过早地优化一下。如果你知道那个开关中会有更多的情况,为什么呢?你有没有运行过探查器?如果没有,它没有用优化。 “过早优化是所有邪恶的根源”。您可能正在优化实际上不是瓶颈的代码的一部分,增加代码复杂性并浪费您自己的时间来编写无任何贡献的代码。

我不知道你正在制作什么类型的应用程序,但经验法则说清晰度是王道,你通常应该选择更简单,更优雅,自我记录的解决方案。

答案 3 :(得分:0)

javac的表现几乎没有优化。所有优化都在运行时使用JIT执行。除非你知道你有性能问题,否则我认为你没有。

PMD抱怨的是清晰度。 e.g。

if (a == 5) {
  // something
} else {
  // something else
}

更清晰
switch(a) {
   case 5:
       // something
       break;
   default:
       // something else
       break;
}