У меня есть очень простой микротест
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
public class Test {
List<Integer> list = new Random().ints(100_000).boxed().collect(toList());
@Benchmark public int mapToInt() {
return list.stream().mapToInt(x -> x * x).sum();
}
}
Когда я запускаю его, я всегда получаю результат, в котором первый разогрев выполняется намного быстрее, чем следующие:
# Warmup Iteration 1: 171.596 us/op
# Warmup Iteration 2: 689.337 us/op
....
Iteration 1: 677.625 us/op
....
Командная строка:
java -jar target/benchmarks.jar .*Test.* -wi 5 -w 1000ms -i 10 -r 1000ms -t 1 -f 5 -tu us
Игра с количеством форков или потоков, похоже, не имеет значения.
Итак, похоже, что какая-то оптимизация возвращается, но я не могу найти, что это такое.
Является ли снижение производительности результатом проблемы с моим эталонным тестом или эта деоптимизация отражает то, что произойдет в реальном приложении?
Примечание: это продолжение Есть ли какое-либо преимущество в вызове map после mapToInt, когда это необходимо?