7

Joshua Bloch in <Effective Java> (Third Edition) mentions that

The operations performed by Stream’s collect method, which are known as mutable reductions, are not good candidates for parallelism because the overhead of combining collections is costly.

I read the docs on Mutable reduction, but I am still not quite sure why reduction is not a good candidate for parallelism. Is it the synchronization?

As @Ravindra Ranwala points out (I also saw this on the Reduction, concurrency, and ordering docs):

It may actually be counterproductive to perform the operation in parallel. This is because the combining step (merging one Map into another by key) can be expensive for some Map implementations.

If so, then are there other major factors we need to care about that might result in low performance?

Didier L
  • 18,905
  • 10
  • 61
  • 103
Hearen
  • 7,420
  • 4
  • 53
  • 63

1 Answers1

5

No it's nothing to do with the synchronization. Consider you have a 1 million Person objects and need to find out all people who live in New York. So a typical stream pipeline would be,

people.parallelStream()
    .filter(p -> p.getState().equals("NY"))
    .collect(Collectors.toList());

Consider a parallel execution of this query. Let's say we have 10 threads executing it in parallel. Each thread will accumulate it's own data set into a separate local container. Finally the 10 result containers are merged to form one large container. This merge will be costly and is an additional step introduced by the parallel execution. Hence parallel execution may not always be faster. Some times sequential execution may be faster than it's parallel counter part.

So always start with a sequential execution. If that makes sense only, you may fall back to it's parallel counterpart at some later point in time.

Ravindra Ranwala
  • 20,744
  • 6
  • 45
  • 63
  • Thanks, I read it in the doc. Are there other **influential** factors that we need to think about? – Hearen Jun 15 '18 at 04:47
  • Thank you, as for **faster** I think I am now not asking about it here. **faster** can be caused by many other factors like **splitting** mechanism, thread **context switching**. What I truly wanna ask is **what are the influential factors the mutation reduction caused to the performance degradation?** Only mutation reduction considered here. – Hearen Jun 15 '18 at 04:56
  • 3
    @Hearen the “the influential factors” are the merging costs. That’s the answer. It’s what Joshua Bloch’s book says, it’s what the documentation says, it’s what this answer says. Why do you insist on assuming that there must be something else? – Holger Jun 15 '18 at 07:26
  • @Holger I got it, yes, you are right about it. Sorry for my rudeness and misunderstanding. Thank you so much to clear out the blur in my mind. Thank you, Holger. – Hearen Jun 15 '18 at 07:37
  • I bet that if you have 1 million people, but only a few of them live in NY, the parallel version will be faster. – ciamej Jun 25 '18 at 12:01
  • @ciamej Based on what criteria did you draw that conclusion? – Ravindra Ranwala Jun 25 '18 at 14:04
  • @RavindraRanwala obviously the fewer people live in NY, the lower the cost of the merge, but still you get the benefits of browsing through the data in parallel. Going to the extremes assume that no one lives in NY, then the cost of the merge might be non-zero, but nonetheless very close to zero. – ciamej Jun 25 '18 at 15:12