RFR: 8180352: Add Stream.toList() method [v4]

Stuart Marks smarks at openjdk.java.net
Mon Nov 30 19:41:00 UTC 2020


On Wed, 25 Nov 2020 17:14:43 GMT, Peter Levart <plevart at openjdk.org> wrote:

>> An alternative with similar performance would be to do a Stream.toArray() and then copy that array into new Object[] and then wrap that copy with listFromTrustedArrayNullsAllowed(). The difference would be in the serialization format of the resulting List and maybe also in the access performance of resulting List (no indirection via the unmodifiableList wrapper and different type for JIT to speculate about). So if we want the resulting List to behave exactly the same in both implementations of toList(), then this alternative might be preferable. WDYT?
>
> Such alternative might also be faster using intrisified array copying method (here measuring just copying overhead):
> 
> Benchmark              (len)  Mode  Cnt       Score      Error  Units
> ToListBench.toList1       10  avgt   10      14.213 ±    0.061  ns/op
> ToListBench.toList1     1000  avgt   10     541.883 ±    3.845  ns/op
> ToListBench.toList1  1000000  avgt   10  753223.523 ± 4656.664  ns/op
> ToListBench.toList2       10  avgt   10       8.810 ±    0.052  ns/op
> ToListBench.toList2     1000  avgt   10     264.748 ±    0.807  ns/op
> ToListBench.toList2  1000000  avgt   10  349518.502 ± 3242.061  ns/op
> 
> https://gist.github.com/plevart/974b67b65210f8dd122773f481c0a603

I don't want to change the default implementation and its specification, for a couple reasons. First, this implementation won't be used in normal operation, as it's overridden by the JDK implementation. (I expect that stream extension libraries will be updated to override it as well.) Second, I'm quite uncomfortable using an internal method from within a default implementation. Right now this method is an agreement between the unmodifiable collections implementation and the ReferencePipeline implementation, and we have complete freedom to change this agreement at any time. If this internal method were used from a default implementation, its behavior would have to be specified in `@implSpec` somehow. Certainly one could write some very vague words for the specification that allow some freedom to make changes, but this has to choose between a better specification and more implementation freedom. I don't see the value in having to make this tradeoff at all.

An extra copy can be avoided via a private agreement between ArrayList and Arrays.asList, which should probably be done in any case.

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

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


More information about the core-libs-dev mailing list