【发布时间】:2019-01-14 15:58:56
【问题描述】:
我写了两个基准来证明 JIT 可能会成为编写精细基准的问题(请跳过我在这里不使用@State):
@Fork(value = 1)
@Warmup(iterations = 2, time = 10)
@Measurement(iterations = 3, time = 2)
@BenchmarkMode(Mode.AverageTime)
public class DeadCodeTraps {
@Benchmark
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public static void summaryStatistics_standardDeviationForFourNumbers() {
final SummaryStatistics summaryStatistics = new SummaryStatistics();
summaryStatistics.addValue(10.0);
summaryStatistics.addValue(20.0);
summaryStatistics.addValue(30.0);
summaryStatistics.addValue(40.0);
summaryStatistics.getStandardDeviation();
}
@Benchmark
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public static void summaryStatistics_standardDeviationForTenNumbers() {
final SummaryStatistics summaryStatistics = new SummaryStatistics();
summaryStatistics.addValue(10.0);
summaryStatistics.addValue(20.0);
summaryStatistics.addValue(30.0);
summaryStatistics.addValue(40.0);
summaryStatistics.addValue(50.0);
summaryStatistics.addValue(60.0);
summaryStatistics.addValue(70.0);
summaryStatistics.addValue(80.0);
summaryStatistics.addValue(90.0);
summaryStatistics.addValue(100.0);
summaryStatistics.getStandardDeviation();
}
}
我以为JIT会消除死代码,所以会同时执行两个方法。但最后,我有:
summaryStatistics_standardDeviationForFourNumbers 0.158 ± 0.046 DeadCodeTraps.summaryStatistics_standardDeviationForTenNumbers 0.359 ± 0.294
为什么 JIT 不优化它? summaryStatistics.getStandardDeviation(); 的结果不会在方法之外的任何地方使用,也不会被它返回。
(我使用的是OpenJDK build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)
【问题讨论】:
-
什么代码死在这里?您是否希望这两个代码花费相同的时间?
-
您期望具体是什么?我对这个结果一点也不感到惊讶
-
summaryStatistics.getStandardDeviation();不在方法范围之外的任何地方使用或返回,因此在 JIT 优化后保留该代码没有意义?或者它可能会保留它,因为它无法确定这段代码是否有任何副作用?