parallelStream() не всегда быстрее: в бенчмарке sum(1..100) в параллели занял ~35 476 нс/оп против ~68 нс/оп в последовательном.Параллельные стримы работают через
ForkJoinPool.commonPool (кол-во потоков: ядра CPU - 1). Порядок обработки элементов не фиксирован, а некорректный reduce может дать неверный итог: identity прибавляется в каждом worker`е (например, reduce(5, sum)).Где параллельные стримы реально полезны:
– Большой объем данных и много вычислений на элемент (так называемая модель NQ: чем больше N*Q, тем выше шанс ускорения; для тривиального суммирования эмпирически N > 10 000).
– Источник легко и равномерно делится: массивы иArrayList. На 1 000 000 элементовArrayListв бенчмарке быстрее в параллели (~2.0 мс vs ~5.4 мс).
– Дешевая операция объединения результатов: reduce/sum обычно выигрывают. Например, сумма наArrayListбыстрее в параллели (~2.07 мс vs ~5.51 мс).
– Хорошая локальность данных. Например, массив примитивов (int[]) даёт больший выигрыш, чем массив ссылок (Integer[]), потому что меньше скачков по памяти.
– Есть I/O с большим числом объектов: поиск по 1500 текстовым файлам черезFiles.walkв параллели быстрее (~10.8 мс vs ~13.3 мс).
📚 Подробнее тут: https://habr.com/ru/companies/spring_aio/articles/1005180/
