JMH - почему JIT не устраняет мой мертвый код - PullRequest
0 голосов
/ 14 января 2019

Я написал два теста, чтобы продемонстрировать, что 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)

1 Ответ

0 голосов
/ 14 января 2019

Если вы говорите о классе Apache Commons Math SummaryStatistics, то это огромный класс. Его конструкция наверняка не будет встроена. Чтобы понять почему, запустите с -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining -XX:-BackgroundCompilation

Устранение мертвого кода происходит после встраивания. Неиспользуемые объекты будут распространяться в обратном направлении, но не встроенный конструктор разорвет цепочку, потому что оптимизатор JIT больше не может быть уверен, что побочных эффектов нет.

Другими словами, код, который вы ожидаете удалить, слишком велик.

...