This is a draft proposal for how we could improve stream performance for the 
case where the streams are empty. Empty collections are common-place. If we 
iterate over them with an Iterator, we would have to create one small Iterator 
object (which could often be eliminated) and if it is empty we are done. 
However, with Streams we first have to build up the entire pipeline, until we 
realize that there is no work to do. With this example, we change 
Collection#stream() to first check if the collection is empty, and if it is, we 
simply return an EmptyStream. We also have EmptyIntStream, EmptyLongStream and 
EmptyDoubleStream. We have taken great care for these to have the same 
characteristics and behaviour as the streams returned by Stream.empty(), 
IntStream.empty(), etc. 

Some of the JDK tests fail with this, due to ClassCastExceptions (our 
EmptyStream is not an AbstractPipeline) and AssertionError, since we can call 
some methods repeatedly on the stream without it failing. On the plus side, 
creating a complex stream on an empty stream gives us upwards of 50x increase 
in performance due to a much smaller object allocation rate. This PR includes 
the code for the change, unit tests and also a JMH benchmark to demonstrate the 
improvement.

-------------

Commit messages:
 - Fixed name typo
 - Update benchmark to have a variable mix of empty streams
 - New microbenchmark to test mixed length streams within a single run
 - Updated empty streams to contain Spliterator state and to prevent stream 
reuse
 - Grouped test results through the use of better field naming
 - Removed old JMH tests that were replaced with more thorough test
 - Increased warmup time to get more consistent results
 - Additional benchmarks to check different types of collections, lengths and 
workloads
 - Added test classes and minor improvements
 - Faster empty streams to reduce object allocation rates

Changes: https://git.openjdk.java.net/jdk/pull/6275/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=6275&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8277095
  Stats: 4269 lines in 15 files changed: 4259 ins; 0 del; 10 mod
  Patch: https://git.openjdk.java.net/jdk/pull/6275.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/6275/head:pull/6275

PR: https://git.openjdk.java.net/jdk/pull/6275

Reply via email to