В вашем примере JVM, скорее всего, полностью оптимизирует цикл, потому что значение result
никогда не читается после вычисления. Вы должны использовать Blackhole
, чтобы потреблять result
, как показано ниже:
@State(Scope.Thread)
@Warmup(iterations = 10, time = 200, timeUnit = MILLISECONDS)
@Measurement(iterations = 20, time = 500, timeUnit = MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {
static double[] array;
static {
int num_of_elements = 100;
array = new double[num_of_elements];
for (int i = 0; i < num_of_elements; i++) {
array[i] = i + 1;
}
}
double result = 0;
@Benchmark
public void baseline(Blackhole blackhole) {
result = 1;
result = result / 1.0;
blackhole.consume(result);
}
@Benchmark
public void testInversionSumForLoop(Blackhole blackhole) {
for (int i = 0; i < array.length; i++) {
result += 1.0 / array[i];
}
blackhole.consume(result);
}
@Benchmark
public void testInversionSumUsingStreams(Blackhole blackhole) {
result = Arrays.stream(array).map(d -> 1 / d).sum();
blackhole.consume(result);
}
}
Этот новый тест показывает разницу в 4 раза, что ожидается. Циклы получают выгоду от ряда оптимизаций в JVM и не включают создание новых объектов, как это делают потоки.
Benchmark Mode Cnt Score Error Units
MyBenchmark.baseline avgt 100 2.437 ± 0.139 ns/op
MyBenchmark.testInversionSumForLoop avgt 100 135.512 ± 13.080 ns/op
MyBenchmark.testInversionSumUsingStreams avgt 100 506.479 ± 4.209 ns/o
Я попытался добавить базовую линию, чтобы показать, сколько стоит одна операция на моей машине. Базовая линия ns/ops
аналогична вашей петле ns/ops
, которую IMO подтверждает, что ваша петля была оптимизирована.
Я бы хотел, чтобы кто-нибудь сказал мне, что послужит хорошей отправной точкой для этого эталонного сценария.
Мое окружение:
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)
Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
Linux 4.15.0-43-generic #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux