Card 08/ 10
Parallel Streams: Why parallel() Can Make a Pipeline Slower
Eight cores, the work spread across all of them, and the whole thing takes longer than before.
A parallel stream splits its source across several threads and combines their results. The splitting and combining cost time before the extra threads save any, so on small inputs or cheap work a parallel pipeline is slower than the plain one.
One word added to a pipeline that was taking too long:
long total = invoices.parallelStream()
.mapToLong(Invoice::pence)
.sum();Going parallel costs something before it saves anything: the source has to be split, tasks have to be handed to a thread pool, and the partial results have to be combined. On a few thousand cheap operations that overhead is most of the time.
| Needs | Why |
|---|---|
| A large source | Thousands of elements at least, usually many more |
| Expensive work per element | Cheap work is dominated by the splitting |
| A source that splits evenly | An ArrayList does; a LinkedList and a file do not |
| No shared mutable state | Otherwise the result is wrong rather than slow |
Every parallel stream also shares one pool of threads by default, so a slow parallel pipeline in one part of an application delays every other one. Measure before adding it, and measure again after.
- Java
- Java Streams
- Performance
← → move through sections and cards