你是说你想测试methodA,而所有其他方法都是private,这就是调用链的样子吗?如果是这样,这里的JMH 无关紧要——将应用哪些优化,仍将应用于该代码。也很难说最终会发生什么优化,因为它们在JVM 上很多,并且还取决于许多其他因素,如操作系统、CPU 等;所以一个“广泛的列表”根本不存在。
例如,根据您在每个方法中的 //do something 中所做的操作,可以省略或不省略该代码。看看这个简化的例子:
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 5)
@Measurement(iterations = 5, time = 5)
public class Sample {
private static final int ME = 1;
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(Sample.class.getSimpleName())
.build();
new Runner(opt).run();
}
@Benchmark
public int methodOne(CustomObjectA a) {
simulateWork();
return 42;
}
@Benchmark
public int methodTwo(CustomObjectA a, Blackhole bh) {
bh.consume(simulateWork());
return 42;
}
@State(Scope.Thread)
public static class CustomObjectA {
}
private static double simulateWork() {
return ME << 1;
}
}
不同之处在于,在方法@987654328@ 中,我使用了所谓的Blackhole(请阅读this 了解更多详细信息),而在methodOne 中,我没有。结果simulateWork从methodOne中被消除,结果显示:
Benchmark Mode Cnt Score Error Units
Sample.methodOne avgt 25 1.950 ± 0.078 ns/op
Sample.methodTwo avgt 25 3.955 ± 0.120 ns/op
另一方面,如果我稍微更改代码以使副作用最小:
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 5)
@Measurement(iterations = 5, time = 5)
public class Sample {
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(Sample.class.getSimpleName())
.build();
new Runner(opt).run();
}
@Benchmark
public int methodOne(CustomObjectA a) {
simulateWorkWithA(a);
return 42;
}
@Benchmark
public int methodTwo(CustomObjectA a) {
return simulateWorkWithA(a) + 42;
}
@Benchmark
public int methodThree(CustomObjectA a, Blackhole bh) {
bh.consume(simulateWorkWithA(a));
return 42;
}
@State(Scope.Thread)
public static class CustomObjectA {
int x = 0;
}
private static int simulateWorkWithA(CustomObjectA a) {
return a.x = a.x + 1;
}
}
simulateWorkWithA(a) 在methodOne 中的消除不会发生:
Benchmark Mode Cnt Score Error Units
Sample.methodOne avgt 25 2.267 ± 0.198 ns/op
Sample.methodThree avgt 25 3.711 ± 0.131 ns/op
Sample.methodTwo avgt 25 2.325 ± 0.008 ns/op
请注意methodOne 和methodTwo 之间几乎没有区别。