Stream.toList() は Collectors.toList() よりもパフォーマンスが良いでしょうか? 質問する

Stream.toList() は Collectors.toList() よりもパフォーマンスが良いでしょうか? 質問する

JDKはAPIを導入しているStream.toList()JDK-8180352以下は、既存の とパフォーマンスを比較するために試したベンチマーク コードですCollectors.toList

@BenchmarkMode(Mode.All)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 20, time = 1, batchSize = 10000)
@Measurement(iterations = 20, time = 1, batchSize = 10000)
public class CollectorsVsStreamToList {

    @Benchmark
    public List<Integer> viaCollectors() {
        return IntStream.range(1, 1000).boxed().collect(Collectors.toList());
    }

    @Benchmark
    public List<Integer> viaStream() {
        return IntStream.range(1, 1000).boxed().toList();
    }
}

結果の概要は次のとおりです。

Benchmark                                                       Mode  Cnt   Score    Error  Units
CollectorsVsStreamToList.viaCollectors                         thrpt   20  17.321 ±  0.583  ops/s
CollectorsVsStreamToList.viaStream                             thrpt   20  23.879 ±  1.682  ops/s
CollectorsVsStreamToList.viaCollectors                          avgt   20   0.057 ±  0.002   s/op
CollectorsVsStreamToList.viaStream                              avgt   20   0.040 ±  0.001   s/op
CollectorsVsStreamToList.viaCollectors                        sample  380   0.054 ±  0.001   s/op
CollectorsVsStreamToList.viaCollectors:viaCollectors·p0.00    sample        0.051            s/op
CollectorsVsStreamToList.viaCollectors:viaCollectors·p0.50    sample        0.054            s/op
CollectorsVsStreamToList.viaCollectors:viaCollectors·p0.90    sample        0.058            s/op
CollectorsVsStreamToList.viaCollectors:viaCollectors·p0.95    sample        0.058            s/op
CollectorsVsStreamToList.viaCollectors:viaCollectors·p0.99    sample        0.062            s/op
CollectorsVsStreamToList.viaCollectors:viaCollectors·p0.999   sample        0.068            s/op
CollectorsVsStreamToList.viaCollectors:viaCollectors·p0.9999  sample        0.068            s/op
CollectorsVsStreamToList.viaCollectors:viaCollectors·p1.00    sample        0.068            s/op
CollectorsVsStreamToList.viaStream                            sample  525   0.039 ±  0.001   s/op
CollectorsVsStreamToList.viaStream:viaStream·p0.00            sample        0.037            s/op
CollectorsVsStreamToList.viaStream:viaStream·p0.50            sample        0.038            s/op
CollectorsVsStreamToList.viaStream:viaStream·p0.90            sample        0.040            s/op
CollectorsVsStreamToList.viaStream:viaStream·p0.95            sample        0.042            s/op
CollectorsVsStreamToList.viaStream:viaStream·p0.99            sample        0.050            s/op
CollectorsVsStreamToList.viaStream:viaStream·p0.999           sample        0.051            s/op
CollectorsVsStreamToList.viaStream:viaStream·p0.9999          sample        0.051            s/op
CollectorsVsStreamToList.viaStream:viaStream·p1.00            sample        0.051            s/op
CollectorsVsStreamToList.viaCollectors                            ss   20   0.060 ±  0.007   s/op
CollectorsVsStreamToList.viaStream                                ss   20   0.043 ±  0.006   s/op

もちろん、ドメイン エキスパートへの最初の質問は、ベンチマーク手順が正しいかどうかです。テスト クラスは MacOS で実行されました。さらに必要な詳細があればお知らせください。

追記ですが、測定値から推測する限りでは、 の平均時間、スループット、およびサンプリング時間はStream.toListよりも優れているようCollectors.toListです。この理解で正しいでしょうか?

ベストアンサー1

Stream::toListは の上に構築されtoArray、 の上には構築されません。には、 を収集よりも高速にする可能性のあるcollect最適化が多数ありますが、これは詳細に大きく依存します。 ストリーム パイプライン (ソースから最終中間操作まで) が の場合、ターゲット配列のサイズを事前に設定できます (コレクターが行う必要がある潜在的な再割り当てではなく)。 パイプラインが より遠い場合、並列実行では結果配列のサイズを事前に設定できるだけでなく、シャードごとの正確なオフセットを計算できるため、各サブタスクは結果を正確な場所にドロップでき、中間結果を最終結果にコピーする必要がなくなります。toArraySIZEDtoListSUBSIZED

したがって、詳細によっては、toListよりもかなり高速になる可能性がありますcollect

おすすめ記事