Java 平方根方法执行第一次尝试需要很长时间

Java 平方根方法执行第一次尝试需要很长时间,java,Java,我有一个Java程序,我正在尝试新的平方根算法,并将它们与Java中的本机Math.sqrt(a)方法进行比较。我觉得奇怪的是,第一次在程序中调用.sqrt(a)方法至少需要50000ns,而之后只需要几千ns。这与在运行程序的最初几分钟内如何计算系统时间有关,还是由于某种原因,这些方法实际上执行得比较慢?启动Java应用程序会有很大的开销 需要加载JVM(java可执行文件) JVM需要引导: 创建和初始化堆 类加载各种系统类 等等 您的类需要类加载。这通常会触发系统类、第三方库等的进一

我有一个Java程序,我正在尝试新的平方根算法,并将它们与Java中的本机
Math.sqrt(a)
方法进行比较。我觉得奇怪的是,第一次在程序中调用
.sqrt(a)
方法至少需要50000ns,而之后只需要几千ns。这与在运行程序的最初几分钟内如何计算系统时间有关,还是由于某种原因,这些方法实际上执行得比较慢?

启动Java应用程序会有很大的开销

  • 需要加载JVM(java可执行文件)
  • JVM需要引导:
    • 创建和初始化堆
    • 类加载各种系统类
    • 等等
  • 您的类需要类加载。这通常会触发系统类、第三方库等的进一步类加载
  • 过了一会儿。。。JIT编译器开始将方法编译为本机代码
  • 当这种情况发生时,GC可能会运行以清除由JIT编译和类加载创建的垃圾
所有这些加起来就意味着巨大的启动成本。。。相比于(例如)在C或C++中实现的应用程序,编译并链接到可执行文件。 然而,这应该与Java中的算法开发和基准测试相关。您只需要以消除“JVM预热”开销的方式进行基准测试。有关详细信息:


@用户7859067评论:

需要非常棒的性能,去本地

我想你的意思是。。。将代码实现为Java本机方法。这对JVM引导开销没有帮助。而且“本机化”并不总是成功的,因为从Java调用自定义本机方法时会有开销


然而,许多
Math
函数的实现都是在本机代码中实现的,这是一个事实。。。为了速度。(JIT编译器有一些调整,可以生成对“内在”本机方法的特殊快速调用,但是(AFAIK)如果不修改JRE代码库,您不能自己使用它…)无论如何,如果您将(纯Java)实现的性能与标准(本机)
Math.sqrt
方法进行比较,你在比较苹果和橙子。

几乎可以肯定的是类加载。试着运行
-verbose:class-verbose:jni-verbose:gc-XX:+printcomployment
,看看是什么造成了这段时间。我认为7859067只是在咆哮,意思是“根本不使用Java”,而不是“使用来自Java的本机方法”。也许吧。然而,他提出了一个重要的观点,对此我给出了一个“直接”的回答,