Pull to refresh

Comments 8

Спасибо за отличный пост и баттл по фактам. Получить такую ответку от Тагира — бесценно :)
Вывод прикладной — хотите быстрого счёта — пишите на компилируемых языках,
для которых счёт — родная поляна. C/C++/Fortran + OpenMP + MPI — хлеб HPC. А пытаться что-то «быстро» посчитать на Java — что возить груз по городу на внедорожнике — приедет, конечно, и привезёт, но если груза много — грузовик эффективнее.
Понятия не имею, как Вы получили такой вывод из этой статьи.
Если производительность скачет в разы в зависимости от настроения JIT-компилятора, причем на тривиальной задаче, значит до потолка производительности на данном железе — куча потраченного впустую процессорного времени. Значит инструмент выбран неправильно.
Это, конечно, не извиняет приминения неэффективных алгоритмов — сортировка пузырьком не оправдана почти(?) никогда, например. И не обесценивает ключевую идею статьи — параллельный код, даже «запертый» с одной стороны, все равно может оказаться быстрее последовательного. Просто язык, на котором эта идея демонстрируется, ставит в процесс проверки всевозможные палки, что противно.
Вы думаете, обычный AOT-компилятор вам будет выдавать код одинаковой производительности на разный профиль? Вы компилируете с использованием рантайм-профиля?
Прогнал бенчмарк дважды на своей машине (спасибо за код). Оба показали почти двукратное «торможение» параллельных стримов:
# JMH version: 1.20
# VM version: JDK 9.0.4, VM 9.0.4+11
# VM invoker: /Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home/bin/java
...
# Run complete. Total time: 00:07:34

Benchmark                                 (size)  Mode  Cnt       Score       Error  Units
ListBenchmark.testForEach                    100  avgt   50      81,505 ±     2,544  us/op
ListBenchmark.testForEach                  10000  avgt   50    7892,829 ±   265,474  us/op
ListBenchmark.testForEach                1000000  avgt   50  806252,255 ± 42423,845  us/op
ListBenchmark.testParallelStreamForEach      100  avgt   50     150,763 ±    11,337  us/op
ListBenchmark.testParallelStreamForEach    10000  avgt   50   10049,075 ±    90,658  us/op
ListBenchmark.testParallelStreamForEach  1000000  avgt   50  970335,925 ± 13154,839  us/op
ListBenchmark.testStreamForEach              100  avgt   50      85,038 ±     5,865  us/op
ListBenchmark.testStreamForEach            10000  avgt   50    9567,694 ±  1179,837  us/op
ListBenchmark.testStreamForEach          1000000  avgt   50  849430,767 ± 71208,049  us/op


И, кстати, в вызов метода checkIndex передавать надо, наверное, index:
// Да, появился такой метод в Java 9, очень удобно!
Objects.checkIndex(index, size);
> И, кстати, в вызов метода checkIndex передавать надо, наверное, index:

Да, спасибо.

> почти двукратное «торможение» параллельных стримов

970 против 806 — это почти двукратное? У вас одна итерация существенно быстрее. Явно процессор другой. Возможно, с улучшенной хардварной поддержкой криптографии. Можно усложнить функцию и посмотреть, что получится. Ну и количество ядер хотя бы указывайте. Вряд ли меньше четырёх, но мало ли.
Да, Вы, конечно же, правы. Двукратное там только для size = 100.

Тем не менее, параллельный стрим на моем процессоре (действительно 4 ядра, i7-7820HQ) не оказывается быстрее. Поковыряю еще, поизменяю функцию.
Sign up to leave a comment.

Articles