3

ここで説明されているように、LINQ での遅延実行を理解しています: LINQ での遅延実行の利点は何ですか?

ただし、遅延実行は、特にマルチスレッド シナリオなどでバグにつながる可能性があります。ロックの外で共有コレクションに対して実行される評価。遅延評価を返すメソッドがいくつかのメソッド層の深さでネストされている場合、適切にロックするように覚えたり追跡したりするのは (少なくとも私にとっては) 非常に難しくなります。

無限シーケンス (フィボナッチなど) のような特殊なケースを省略し、コレクションのフィルタリングが完了したと見なされる (つまり、消費者が結果をさらにフィルタリングする可能性は低い) と仮定すると、返されるときに「最良のアプローチ」と見なされるものメソッドからの IEnumerable のコレクション -- 既に評​​価または延期されている必要がありますか?

注:「最良のアプローチ」は、他の手段の効率/コードの安全性の観点から定義できます。応答で確認してください。コミュニティがこれをどのように行っているか知りたいです。

後続の質問: 結果が評価されるか遅延されるかをメソッド名で明示的に述べることに意味はありますか?

4

1 に答える 1

2

作成するコードのほとんどはマルチスレッドではありません。実際、Enumable を積極的に評価したい場合、私が考えることができる理由は 3 つしかありません。

  1. マルチスレッド環境で必要です。代わりに、リストまたは配列にする必要があります。
  2. 列挙可能なものへのランダムアクセスが必要です。代わりに、リストまたは配列にする必要があります。
  3. 評価がいつ行われるかを制御したい (たとえば、コストがかかる場合)。

それ以外の場合は、遅延実行を使用できるようにする必要があります。これにより、実際に必要なポイントまで評価が延期され、適用するフィルターによってはより高速になる場合があります。たとえば、bigquery.First()よりも高速な場合がありますbigquery.ToArray().First()。ユーザーがフィルタリングを完了したことを確認できますか?

また、ランタイムは特定の LINQ クエリを最適化します。この例は、Jon Skeetの記事LINQ To Objects とネストされた "Where" 呼び出しのパフォーマンスから取られています。

// Normal LINQ query
var query = list.Where(x => Condition1(x))
                .Where(x => Condition2(x))
                .Select(x => Projection1(x))
                .Select(y => Projection2(y));

// After optimization
var query = list.WhereSelect(x => Condition1(x) && Condition2(x),
                             x => Projection2(Projection1(x)); 

ところで、メソッドは可能な限り具体的な可視型を返す必要があります。たとえば、内部でT[]配列またはリストを処理するメソッドは、通常、 のみを返すべきではありません。結果を不変にしたい場合は、代わりに a でラップします。List<T>IEnumerable<T>ReadOnlyCollection<T>

于 2013-03-20T16:22:09.053 に答える