On Fri, 5 Nov 2021 12:53:46 GMT, kabutz <[email protected]> wrote:
> 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.
src/java.base/share/classes/java/util/Arrays.java line 5448:
> 5446: public static <T> Stream<T> stream(T[] array, int startInclusive,
> int endExclusive) {
> 5447: var spliterator = spliterator(array, startInclusive,
> endExclusive);
> 5448: if (startInclusive == endExclusive) return Stream.empty();
Can't we just add the `if` statement to before the `spliterator` is computed?
-------------
PR: https://git.openjdk.java.net/jdk/pull/6275