Java什么时候比c ++快(或者什么时候JIT比预编译更快)?

可能的重复:
JIT 编译器与脱机编译器

我听说在某些情况下,由于JIT优化,Java程序或java程序的一部分能够比C++(或其他预编译代码)中的“相同”代码执行得更快。这是因为编译器能够确定某些变量的范围,避免某些条件并在运行时拉取类似的技巧。

你能举一个(或更好的 - 一些)例子,这适用吗?也许可以概述编译器能够优化字节码的确切条件,超越预编译代码的可能性?

注意:这个问题不是关于将Java与C++进行比较。它是关于JIT编译的可能性。请不要燃烧。我也不知道有任何重复。如果你是,请指出他们。


答案 1

在实践中,您可能会发现在这些情况下,您天真编写的Java代码优于您天真的编写的C++代码(所有这些都是我个人观察到的):

  • 大量的小内存分配/解除分配。主要的JVM具有非常高效的内存子系统,垃圾回收可能比要求显式释放更有效(另外,如果它真的想要,它可以转移内存地址等)。

  • 通过方法调用的深层层次结构进行高效访问。JVM非常擅长省略任何不必要的东西,根据我的经验,通常比大多数C++编译器(包括gcc和icc)更好。部分原因是它可以在运行时进行动态分析(即它可以过度优化,只有在检测到问题时才取消优化)。

  • 将功能封装到小型短期对象中。

在每种情况下,如果你付出努力,C++可以做得更好(在自由列表和块分配/解除分配的内存之间,C++几乎可以在每一个特定情况下击败JVM内存系统;使用额外的代码,模板和聪明的宏,你可以非常有效地折叠调用堆栈;你可以在C++拥有小的、部分初始化的堆栈分配对象,这些对象的性能优于JVM的短期对象模型)。但你可能不想付出努力。


答案 2

一些例子:

  • JIT编译器可以使用例如最新的SSE扩展来生成非常特定于CPU的机器代码,这些扩展在需要运行各种CPU的预编译代码中不会使用。
  • JIT知道虚拟方法(Java中的默认值)何时不会在任何地方被覆盖,因此可以内联(尽管这需要在加载覆盖该方法的新类时取消内联它的能力;当前的Java JIT编译器实际上这样做)。
  • 与此相关的是,逃逸分析允许对特定情况进行透视优化。

推荐