java - 是什么让最新版本的 JVM 更快?

标签 java performance scala jvm native-code

我最近看到多个声明,谈论 Java(以及基于 JVM 的语言,如 Scala)在性能上如何与 C/C++ 代码相媲美。

例如,来自 ScalaLab project 的描述:

The speed of Scala based scripting, that approaches the speed of native and optimized Java code, and thus is close to, or even better from C/C++ based scientific code!



有人可以指出我对这些 JVM 优化的总结吗?是否有任何真实的基准支持这种说法或提供一些真实世界的比较?

最佳答案

表演技巧

首先,这取决于您所谈论的 JVM,因为有几个 - 但我假设您指的是 Oracle HotSpot(并且在任何情况下,其他顶级 JVM 都将使用类似的技术)。

对于那个 JVM,this list来自 HotSpot 内部 wiki 提供了一个很好的开始(子页面详细介绍了一些更有趣的技术)。如果您只是在寻找技巧 list ,请访问 wiki has that too ,尽管要理解它们,您可能需要在 google 上搜索各个术语。

并非所有这些最近都已实现,但一些大的已经实现(范围检查省略、转义分析、 super 词优化)——至少对于“最近”的松散定义。

接下来让我们看一下 C/C++ 与 Java 的相对性能图,以及为什么上述技术有助于缩小差距,或者在某些情况下实际上赋予 Java 和本地编译语言的内在优势。

Java 与 C/C++

在高层次上,优化是您在任何体面的 C 和 C++ 等 native 语言编译器中看到的东西的混合,以及减少 Java/JVM 特定功能和安全检查的影响所需的东西,例如作为:

  • 转义分析可以减轻(在某种程度上)对象的无堆栈分配
  • 内联缓存和类层次结构分析,可缓解“每个函数都是虚拟的”
  • 范围检查消除,减轻“每个数组访问都进行范围检查”

  • 许多这些特定于 JVM 的优化仅有助于使 JVM 与本地语言达到同等水平,因为它们正在解决本地语言不必处理的障碍。然而,一些优化是静态编译语言无法管理的(或者在某些情况下只能通过配置文件引导的优化来管理,这种情况很少见,无论如何都必须一刀切):
  • 仅动态内联 HitTest 门的代码
  • 基于实际分支/开关频率的代码生成
  • 动态生成 CPU/指令集感知代码(甚至在代码编译后发布的 CPU 功能!)1
  • 取消从未执行的代码
  • 注入(inject)与应用程序代码交错的预取指令
  • 安全指向支持的整个技术系列

  • 共识似乎是,Java 通常在中等优化级别(例如 gcc -O2)生成速度与优秀 C++ 编译器相似的代码,尽管很大程度上取决于确切的基准测试。像 HotSpot 这样的现代 JVM 往往在低级数组遍历和数学方面表现出色(只要竞争编译器不是矢量化 - 这很难被击败),或者在竞争代码执行相似数量的分配时具有大量对象分配的场景(JVM 对象分配 + GC 通常比 malloc 快),但是当典型 Java 应用程序的内存损失是一个因素时,堆栈分配被大量使用,或者向量化编译器或内在函数使标度向 native 代码倾斜时会下降。

    如果您搜索 Java 与 C 的性能,您会发现很多人已经解决了这个问题,但严格程度各不相同。这是first one I stumbled across ,这似乎显示了 gcc 和 HotSpot 之间的粗略联系(即使在这种情况下是 -O3)。 This post如果您想了解单个基准测试如何在每种语言中进行多次迭代,相互跨越 - 并显示双方优化的一些限制,那么链接的讨论可能是一个更好的开始。

    *并不是真正特定于 JVM - 大多数也适用于其他安全或托管语言,如 CLR

    1 随着新指令集(特别是 SIMD 指令,但有 others)以某种频率发布,这种特殊的优化变得越来越重要。自动向量化可以大大加快一些代码的速度,虽然 Java 在这里慢得离谱,但它们至少是 catching up一点点。

    关于java - 是什么让最新版本的 JVM 更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16138888/

    相关文章:

    Java - 如何显示独立于货币区域设置的多种货币?

    java - 需要有关java中日期时间函数的帮助

    Java不同类型的对象作为相同的参数

    python - 使用 pandas 访问器减少运行时间

    python - 优化 CPU 上的 Tensorflow 图像识别

    html - 哪种图像扩展在质量和性能(速度)方面都更好?

    json - 为对象序列提供 JsonFormat

    scala - 如何在scaladoc中转义/*?

    java - 在Java中向日期添加一天时,不更新月份

    json - 如何在 Play Json 中使用 Joda DateTime