1. ホーム

[解決済み】Java 8 Streams: 複数のフィルタと複雑な条件の比較

2022-03-29 06:37:55

質問

をフィルタリングしたい場合があります。 Stream を複数の条件で指定します。

myList.stream().filter(x -> x.size() > 10).filter(x -> x.isCool()) ...

あるいは、同じように複雑な条件と シングル filter :

myList.stream().filter(x -> x.size() > 10 && x -> x.isCool()) ...

私の推測では、2番目のアプローチの方がパフォーマンス特性が優れていると思いますが、私は 知る ということです。

読みやすさでは最初のアプローチが勝りますが、パフォーマンスではどちらが良いのでしょうか?

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

両方の選択肢で実行しなければならないコードは非常に似ているため、結果を確実に予測することはできません。基本的なオブジェクト構造は異なるかもしれませんが、ホットスポットオプティマイザにとっては挑戦ではありません。ですから、もし違いがあるとしても、より速く実行できるのは、他の周辺条件によるのです。

2つのフィルターインスタンスを組み合わせると、より多くのオブジェクトが生成されるため、デリゲートコードも増えることになりますが、ラムダ式ではなくメソッド参照を使用すると、この状況は変わります。 filter(x -> x.isCool())filter(ItemType::isCool) . こうすることで、ラムダ式のために作られた合成デリゲートメソッドを排除することができます。つまり、2つのメソッド参照を使った2つのフィルタを組み合わせても、 1つのメソッドを使った場合と同じかそれ以下のデリゲーションコードになる可能性があります。 filter というラムダ式で呼び出すと && .

しかし、前述の通り、このようなオーバーヘッドはHotSpotのオプティマイザによって解消され、無視できる程度になります。

理論的には、2つのフィルターは1つのフィルターよりも簡単に並列化できますが、それはかなり計算量の多いタスクにのみ関係します¹。

だから、単純な答えはないんです。

要するに、臭気検知の閾値以下では、そんな性能差は考えなくていいということです。より読みやすいものを使いましょう。


¹...そして、後続のステージの並列処理を行う実装が必要になりますが、これは現在標準のStream実装では行われていない道です。