1. ホーム
  2. java

[解決済み] 可能な限り常にパラレルストリームを使用した方がいいのでしょうか?

2022-03-16 01:27:17

質問

Java 8とラムダを使えば、コレクションをストリームとして反復処理するのは簡単だし、並列ストリームを使うのも同じように簡単だ。以下の2つの例 ドキュメント 2つ目はparallelStreamを使用したものです。

myShapesCollection.stream()
    .filter(e -> e.getColor() == Color.RED)
    .forEach(e -> System.out.println(e.getName()));

myShapesCollection.parallelStream() // <-- This one uses parallel
    .filter(e -> e.getColor() == Color.RED)
    .forEach(e -> System.out.println(e.getName()));

順番を気にしない限りは、常に並列を使うのが得策でしょうか?より多くのコアで作業を分担したほうが早いと思うのですが。

他に考慮すべき点はありますか?どのような場合に並列ストリームを使用し、どのような場合に非並列を使用すべきなのでしょうか?

(この質問は、並列ストリームをどのように、いつ使うかについての議論のきっかけにするためのものであり、常に使うことが良いアイデアだと私が思っているからではありません)。

どのように解決するのですか?

並列ストリームは、逐次ストリームに比べてはるかに高いオーバーヘッドを持ちます。スレッドを調整するのに多大な時間がかかります。私は、デフォルトでは逐次ストリームを使用し、以下の場合にのみ並列ストリームを検討します。

  • 処理するアイテムが大量にある(または、各アイテムの処理に時間がかかり、並列化できる)

  • そもそも性能に問題がある

  • すでにマルチスレッド環境でプロセスを実行していない(例:Webコンテナで、すでに多くのリクエストを並列処理している場合、各リクエストの内部に並列処理を追加すると、プラスよりもマイナスの効果が大きくなる可能性があります)。

あなたの例では、パフォーマンスはとにかく System.out.println() この処理を並列化しても効果はない、もしくはマイナスにしかなりません。

さらに、並列ストリームが魔法のようにすべての同期の問題を解決してくれるわけではないことを覚えておいてください。もし、そのプロセスで使われる述語や関数が共有資源を使うなら、すべてがスレッドセーフであることを確認する必要があります。特に、副作用は、並列化した場合に本当に心配しなければならないことです。

いずれにせよ、推測ではなく、測定することです。並列化する価値があるかどうかは、測定してみなければわかりません。