Java 8 Java11中的空方法明显比Java8慢
我在使用1.21比较JDK 8和11的性能时遇到了一些令人惊讶的数字:Java 8 Java11中的空方法明显比Java8慢,java-8,java-11,jmh,Java 8,Java 11,Jmh,我在使用1.21比较JDK 8和11的性能时遇到了一些令人惊讶的数字: Java版本:1.8.0192,供应商:Oracle公司 基准模式Cnt分数误差单位 MyBenchmark.emptyMethod avgt 25 0.362±0.001 ns/op Java版本:9.0.4,供应商:Oracle公司 基准模式Cnt分数误差单位 MyBenchmark.emptyMethod avgt 25 0.362±0.001 ns/op Java版本:10.0.2,供应商:Oracle公司 基准模式
Java版本:1.8.0192,供应商:Oracle公司
基准模式Cnt分数误差单位
MyBenchmark.emptyMethod avgt 25 0.362±0.001 ns/op
Java版本:9.0.4,供应商:Oracle公司
基准模式Cnt分数误差单位
MyBenchmark.emptyMethod avgt 25 0.362±0.001 ns/op
Java版本:10.0.2,供应商:Oracle公司
基准模式Cnt分数误差单位
MyBenchmark.emptyMethod avgt 25 0.723±0.001 ns/op
Java版本:11.0.1,供应商:Oracle公司
基准模式Cnt分数误差单位
MyBenchmark.emptyMethod avgt 25 0.724±0.002 ns/op
OpenJDK 11和12的性能与OracleJDK 11类似。为了简洁起见,我省略了他们的数字
我知道微基准并不表示实际应用程序的性能行为。不过,我很好奇这种差异是从哪里来的有什么想法吗?
以下是整个基准: pom.xml:
package jmh;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark
{
@Benchmark
public void emptyMethod()
{
}
}
4.0.0
jmh
空方法
1.0-快照
罐子
JMH基准测试示例:Java
org.openjdk.jmh
jmh核
${jmh.version}
org.openjdk.jmh
jmh发生器
${jmh.version}
假如
UTF-8
1.21
1.8
基准
org.apache.maven.plugins
maven enforcer插件
1.4.1
强制执行版本
执行
3
org.apache.maven.plugins
maven编译器插件
3.8.0
${javac.target}
${javac.target}
${javac.target}
org.apache.maven.plugins
maven阴影插件
3.2.1
包裹
阴凉处
${uberjar.name}
org.openjdk.jmh.Main
*:*
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
maven清洁插件
2.6.1
maven部署插件
2.8.2
maven安装插件
2.5.2
maven jar插件
3.1.0
maven javadoc插件
3.0.0
maven资源插件
3.1.0
maven站点插件
3.7.1
maven源插件
3.0.1
maven surefire插件
2.22.0
src/main/java/jmh/MyBenchmark.java:
package jmh;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark
{
@Benchmark
public void emptyMethod()
{
}
}
下面是我使用的特定于Windows的脚本。将其转换到其他平台应该很简单:
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_192
call mvn -V -Djavac.target=1.8 clean install
"%JAVA_HOME%\bin\java" -jar target\benchmarks.jar
set JAVA_HOME=C:\Program Files\Java\jdk-9.0.4
call mvn -V -Djavac.target=9 clean install
"%JAVA_HOME%\bin\java" -jar target\benchmarks.jar
set JAVA_HOME=C:\Program Files\Java\jdk-10.0.2
call mvn -V -Djavac.target=10 clean install
"%JAVA_HOME%\bin\java" -jar target\benchmarks.jar
set JAVA_HOME=C:\Program Files\Java\oracle-11.0.1
call mvn -V -Djavac.target=11 clean install
"%JAVA_HOME%\bin\java" -jar target\benchmarks.jar
我的运行时环境是:
ApacheMaven 3.6.0(97c98ec64a1fdfee7767ce5ffb20918da4f719f3;2018-10-24T14:41:47-04:00)
Maven主页:C:\Program Files\apache-Maven-3.6.0\bin\。。
默认区域设置:en_CA,平台编码:Cp1252
操作系统名称:“windows 10”,版本:“10.0”,arch:“amd64”,系列:“windows”
更具体地说,我正在运行Microsoft Windows[Version 10.0.17763.195]您正在测量的是空基准,而不是空方法。换句话说,测量处理基准本身的最小基础结构代码。这很容易剖析,因为在热路径上只需要一些指令。JMH的-prof perfasm
或-prof xperfasm
将在几秒钟内为您提供最热门的指令
我认为这种影响是由于,见:
8u191:0.389±0.029纳秒/升
[目前为止一切顺利]
3.60% ↗ ...a2: movzbl 0x94(%r8),%r10d
0.63% │ ...aa: add $0x1,%rbp
32.82% │ ...ae: test %eax,0x1765654c(%rip) ; global safepoint poll
58.14% │ ...b4: test %r10d,%r10d
╰ ...b7: je ...a2
0.31% ↗ ...70: movzbl 0x94(%r9),%r10d
0.19% │ ...78: mov 0x108(%r15),%r11 ; reading the thread-local poll addr
25.62% │ ...7f: add $0x1,%rbp
35.10% │ ...83: test %eax,(%r11) ; thread-local safepoint poll
34.91% │ ...86: test %r10d,%r10d
╰ ...89: je ...70
5.64% ↗ ...62: movzbl 0x94(%r8),%r10d
0.91% │ ...6a: add $0x1,%rbp
34.36% │ ...6e: test %eax,0x179be88c(%rip) ; global safepoint poll
54.79% │ ...74: test %r10d,%r10d
╰ ...77: je ...62
11.0.2:0.585±0.014 ns/op[oops,回归]
3.60% ↗ ...a2: movzbl 0x94(%r8),%r10d
0.63% │ ...aa: add $0x1,%rbp
32.82% │ ...ae: test %eax,0x1765654c(%rip) ; global safepoint poll
58.14% │ ...b4: test %r10d,%r10d
╰ ...b7: je ...a2
0.31% ↗ ...70: movzbl 0x94(%r9),%r10d
0.19% │ ...78: mov 0x108(%r15),%r11 ; reading the thread-local poll addr
25.62% │ ...7f: add $0x1,%rbp
35.10% │ ...83: test %eax,(%r11) ; thread-local safepoint poll
34.91% │ ...86: test %r10d,%r10d
╰ ...89: je ...70
5.64% ↗ ...62: movzbl 0x94(%r8),%r10d
0.91% │ ...6a: add $0x1,%rbp
34.36% │ ...6e: test %eax,0x179be88c(%rip) ; global safepoint poll
54.79% │ ...74: test %r10d,%r10d
╰ ...77: je ...62
11.0.2,-XX:-threadlocal握手:0.399±0.048 ns/op[返回到8u性能]
3.60% ↗ ...a2: movzbl 0x94(%r8),%r10d
0.63% │ ...aa: add $0x1,%rbp
32.82% │ ...ae: test %eax,0x1765654c(%rip) ; global safepoint poll
58.14% │ ...b4: test %r10d,%r10d
╰ ...b7: je ...a2
0.31% ↗ ...70: movzbl 0x94(%r9),%r10d
0.19% │ ...78: mov 0x108(%r15),%r11 ; reading the thread-local poll addr
25.62% │ ...7f: add $0x1,%rbp
35.10% │ ...83: test %eax,(%r11) ; thread-local safepoint poll
34.91% │ ...86: test %r10d,%r10d
╰ ...89: je ...70
5.64% ↗ ...62: movzbl 0x94(%r8),%r10d
0.91% │ ...6a: add $0x1,%rbp
34.36% │ ...6e: test %eax,0x179be88c(%rip) ; global safepoint poll
54.79% │ ...74: test %r10d,%r10d
╰ ...77: je ...62
我认为这在很大程度上是可见的,主要是在像这样的紧密循环中
UPD:希望有更多的细节。
-perfasm教授会告诉你一个更完整的故事。或者Windows上的xperfasm教授。真的很有趣。还有谁。。。谢谢你的回答。为什么JMH不减去