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

Peter Levart plevart at openjdk.java.net
Wed Nov 25 17:17:57 UTC 2020


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

>> This is the default implementation in the Stream interface, which is overridden by an implementation in the ReferencePipeline class, so it will rarely be used in normal operation. The ReferencePipeline version (part of this changeset) is based on toArray() and avoids any copying. I'm thus not inclined to add new interfaces in order to support this default implementation.
>> 
>> As written it's true that the default implementation does perform apparently redundant copies, but we can't be assured that toArray() actually returns a freshly created array. Thus, we wrap it using Arrays.asList and then copy it using the ArrayList constructor. This is unfortunate but necessary to avoid situations where someone could hold a reference to the internal array of a List, allowing modification of a List that's supposed to be unmodifiable.
>
> 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

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

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


More information about the core-libs-dev mailing list