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