【发布时间】:2017-10-12 11:37:20
【问题描述】:
我正在尝试比较两个主要 Java 实现的性能:Oracle 和 IBM 在运行以下测试时:
public class HarmonicSeriesTest {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
final int limit = 20;
double sum = 0.0;
long n = 0;
while (sum < limit) {
n++;
sum += 1.0 / n;
}
long duration = System.currentTimeMillis() - startTime;
System.out.printf("n is %d\n", n);
System.out.printf("Executed in %d miliseconds\n", duration);
}
}
通过运行上面的代码:
- IBM JRE 1.8.0
java 版本“1.8.0”Java(TM) SE 运行时环境(构建 pwa6480sr3fp22-20161213_02(SR3 FP22)) IBM J9 VM(内部版本 2.8,JRE 1.8.0 Windows 10 amd64-64 压缩参考 20161209_329148 (JIT 启用,启用 AOT)J9VM - R28_20161209_1345_B329148 JIT - tr.r14.java.green_20161207_128946 GC - R28_20161209_1345_B329148_CMPRSS J9CL - 20161209_329148) JCL - 20161213_01 基于Oracle jdk8u111-b14
- Oracle JRE 1.8.0_131
java 版本 "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64 位服务器 VM(内部版本 25.131-b11,混合模式)
- Sun JRE 1.5.0_22
java 版本“1.5.0_22”Java(TM) 2 运行时环境,标准 版本 (build 1.5.0_22-b03) Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03,混合模式)
我一直得到以下结果:
- IBM JRE 1.8.0 编译器合规级别 1.8
n is 272400600 Executed in 1024 miliseconds
- Oracle JRE 1.8.0_131 编译器合规级别 1.8
n is 272400600 Executed in 2002 miliseconds
- Sun JRE 1.5.0_22 编译器合规级别 1.5
n is 272400600 Executed in 1506 miliseconds
如您所见,Oracle JRE 比 IBM JRE 慢 100%,比 Sun JRE 慢 25%。 Oracle 和 IBM 实现之间的差距很大,而且 Oracle JRE 看起来像是 Sun JRE 的回归。
有没有人解释一下为什么 Java 的“官方”实现这么慢?
我对使用 JMH 没有兴趣,因为我不想对任何东西进行基准测试。
下面是我用来测试的硬件配置:
【问题讨论】:
-
最好在 JMH 这样的工具中进行测试。不同的 Java 运行时将启动得更快,并在稍后进行优化。例如,循环将被展开,热点将使这些测试几乎毫无意义。即代码运行得越多,它就会越快
-
你是在测试编译器还是机器?为什么不尝试 n 作为双精度数?所有你需要改变的是 long n = 0;将 n = 0.0 翻倍; (以及打印语句。)顺便说一句:n++ 其中 n 是一个双重作品。
-
@Marichyasana 测试的重点是让不同的类型参与除法。