6

次のリクエストは自動的に「最適化」されますか?

var result = initial
                .Where(Predicate1)
                .Where(Predicate2)
                .Where(Predicate3);

これは、

var result = initial
                .Where(e => Predicate1(e) && Predicate2(e) && Predicate3(e));

2 つのステートメントのうち、どちらがより最適化されていますか? それとも同一ですか?

4

2 に答える 2

10

コンパイルされたコードは述語を結合しませんが、実行は基本的に結合します。Linq の Where メソッドは、List を渡すと WhereListIterator を返します。WhereListIterator には、述語を組み合わせた新しい WhereListIterator を返す独自の Where メソッド実装があります。次のようになります。

return new Enumerable.WhereListIterator<T>(this.source, Enumerable.CombinePredicates<T>(this.predicate, predicate)

ここで、this.source はリスト、this.predicate は最初の Where の述語、predicate は 2 番目の Where からのものです。

CombinePredicates は、次のコードを含むデリゲートを返します。

if (predicate1(source)) return predicate2(source);
return false;

したがって、チェーンされた Where 句は次のようになります。

if (predicate1(source)) {
    if (predicate2(source) {
        return predicate3(source) {
    } 
    return false;
 }
 return false;

リストが小さい場合は、&& を使用して単一の Where で述語を結合する方が効率的ですが、リストのサイズが大きくなると、2 つのオプションの実行時間が類似する可能性があります。違いを定量化するには、プロファイルを作成する必要があります。あまり大きくないので問題ないと思います。

于 2013-08-06T13:28:41.287 に答える