Performance update

Brian Goetz brian.goetz at oracle.com
Wed Apr 3 10:53:30 PDT 2013


With Doug's help, we've been beating on the performance of the Streams 
implementation.  We've been in pretty good shape all along with 
per-element overhead, since we departed from Iterator very early on. 
But we've been struggling with startup overhead.  As the API has 
stabilized and many simplifying assumptions have been made (e.g., recent 
simplification of sequential/parallel, outlawing "reuse", outlawing 
"forked" streams, etc), we've recently been able to make a refactoring 
pass that reduces the object count for setting up a stream.  Highlights 
of this include:
  - merging PipelineHelper into AbstractPipeline;
  - eliminating the Supplier<Spliterator> capture even when the client 
provides a late-binding Spliterator;
  - Recasting the Op implementations as "extends XxxPipeline" instead of 
having the pipeline object encapsulate the Op (2x reduction)
  - merging TerminalOp and TerminalSink for some operations, including 
forEach

Some of this is already in, but the rest should be going in the next few 
days.  It does not affect the public API at all.

We've also opened the door to implementing some parallel stateful 
operations without full barriers, so they can be better pipelined.  For 
example, limit/substream on a stream that is SIZED+SUBSIZED can be 
expressed as a wrapping spliterator without touching the data or 
computing elements that won't be part of the result.  The new 
implementation strategy permits this, though we have to do some more 
work to upgrade the candidate operations.

Further, many of the "expensive" setup operations are now avoided for 
sequential and stateless parallel pipelines, only being paid by parallel 
pipelines with stateful ops.


More information about the lambda-libs-spec-observers mailing list