Java BigInteger 源代码性能基准测试

And*_*agy 2 java math performance benchmarking biginteger

我试图弄清楚为什么 Java 的 BigInteger 乘法基准始终比使用复制到我的项目的 BigInteger.java 源代码中的实例快 3 倍。使用 jmh 运行基准测试。这是一个示例输出,请注意,加法的运行效果大致相同。

\n
Benchmark                                 Mode  Cnt       Score       Error  Units\nBenchmarkTest.javaBigInteger_add         thrpt    5  856062.338 \xef\xbf\xbd 34040.923  ops/s\nBenchmarkTest.sourceBigInteger_add       thrpt    5  842421.746 \xef\xbf\xbd 39630.112  ops/s\nBenchmarkTest.javaBigInteger_multiply    thrpt    5  525649.635 \xef\xbf\xbd 15271.083  ops/s\nBenchmarkTest.sourceBigInteger_multiply  thrpt    5  133944.766 \xef\xbf\xbd  1832.857  ops/s\n
Run Code Online (Sandbox Code Playgroud)\n

我这样做的原因是试图将其中的一部分移植到 Kotlin,我注意到基准测试有点慢。为了看看它是否与 Kotlin 有关,我从图片中删除了它,并在纯 java 中执行了所有操作,得到了完全相同的结果。如果源代码/算法完全相同,为什么这个基准测试会有如此大的差异?

\n

使用此代码的项目: https://github.com/asheragy/BigInteger-Benchmark

\n

Rob*_*sen 7

一些(甚至可能是大多数)JVM 具有许多内部函数,用于代替 Java 代码来执行各种计算密集型操作。更多详细信息可以在这个问题的答案中找到。这些内在函数之一,multiplyToLen专门处理BigInteger乘法。

\n

通过更改文件jmh中的配置来禁用此内部函数的使用后build.gradle,如下所示:

\n
jmh {\n    warmupIterations = 2 \n    iterations = 5 \n    fork = 1 \n    jvmArgsPrepend = [\'-XX:+UnlockDiagnosticVMOptions\', \'-XX:-UseMultiplyToLenIntrinsic\']\n}\n
Run Code Online (Sandbox Code Playgroud)\n

JDK 11.0.11, OpenJDK 64-Bit Server VM, 11.0.11+8-jvmci-21.1-b05我在 x86-64 架构上的OpenJDK 11 ( ) 上得到以下乘法基准测试结果:

\n
Benchmark                        Mode  Cnt       Score      Error  Units\nBenchmarkTest.javaBigInteger    thrpt    5  107476.070 \xc2\xb1 8059.020  ops/s\nBenchmarkTest.sourceBigInteger  thrpt    5  108011.737 \xc2\xb1 7105.221  ops/s\n
Run Code Online (Sandbox Code Playgroud)\n

这几乎完全缩小了两种实现之间的差距。

\n

可能还有其他配置选项的作用较小,但我认为一般来说,答案是针对未应用于自定义实现的标准 JDK 类进行了各种编译器/运行时优化。

\n