В рамках моего исследования различий между использованием сложного фильтра или нескольких фильтров в потоках я заметил, что производительность в Java 12 намного ниже, чем в Java 8.
Есть ли какое-то объяснение этим странным результатам? Я что-то здесь упустил?
Конфигурация:
-
Ява 8
- Среда выполнения OpenJDK (сборка 1.8.0_181-8u181-b13-2 ~ deb9u1-b13)
- 64-разрядная серверная виртуальная машина OpenJDK (сборка 25.181-b13, смешанный режим)
-
Ява 12
- Среда выполнения OpenJDK (сборка 12 + 33)
- OpenJDK 64-битная серверная виртуальная машина (сборка 12 + 33, смешанный режим, совместное использование)
-
Опции VM:
-XX:+UseG1GC
-server
-Xmx1024m
-Xms1024m
- Процессор: 8 ядер
Пропускная способность JMH:
- Разминка: 10 итераций по 1 с
- Измерение: 10 итераций по 1 с
- Темы: 1 поток, будет синхронизировать итерации
- Единицы: ops/s
Код
Стрим + комплексный фильтр
public void complexFilter(ExecutionPlan plan, Blackhole blackhole) {
long count = plan.getDoubles()
.stream()
.filter(d -> d < Math.PI
&& d > Math.E
&& d != 3
&& d != 2)
.count();
blackhole.consume(count);
}
Поток + несколько фильтров
public void multipleFilters(ExecutionPlan plan, Blackhole blackhole) {
long count = plan.getDoubles()
.stream()
.filter(d -> d > Math.PI)
.filter(d -> d < Math.E)
.filter(d -> d != 3)
.filter(d -> d != 2)
.count();
blackhole.consume(count);
}
Параллельный поток + комплексный фильтр
public void complexFilterParallel(ExecutionPlan plan, Blackhole blackhole) {
long count = plan.getDoubles()
.stream()
.parallel()
.filter(d -> d < Math.PI
&& d > Math.E
&& d != 3
&& d != 2)
.count();
blackhole.consume(count);
}
Параллельный поток + несколько фильтров
public void multipleFiltersParallel(ExecutionPlan plan, Blackhole blackhole) {
long count = plan.getDoubles()
.stream()
.parallel()
.filter(d -> d > Math.PI)
.filter(d -> d < Math.E)
.filter(d -> d != 3)
.filter(d -> d != 2)
.count();
blackhole.consume(count);
}
Старая мода Java итерация
public void oldFashionFilters(ExecutionPlan plan, Blackhole blackhole) {
long count = 0;
for (int i = 0; i < plan.getDoubles().size(); i++) {
if (plan.getDoubles().get(i) > Math.PI
&& plan.getDoubles().get(i) > Math.E
&& plan.getDoubles().get(i) != 3
&& plan.getDoubles().get(i) != 2) {
count = count + 1;
}
}
blackhole.consume(count);
}
Вы можете попробовать самостоятельно, запустив команду docker:
Для Java 8:
запуск докера -it volkodav/java-filter-benchmark: java8
Для Java 12:
запуск докера -it volkodav/java-filter-benchmark: java12
Исходный код: