5

このコードを置き換えました:

foreach( var source in m_sources )
{
    if( !source.IsExhausted )
    {
        ....
    }
}

これで:

foreach( var source in m_sources.Where( src => !src.IsExhausted ) )
{
   ...
}

これでコードは (私には) 良くなりましたが、ここで実際に何が起こっているのか疑問に思っています。この場合、パフォーマンスが心配です。このフィルターを適用することで、何らかのコンパイラ マジックが発生することを意味する場合は、悪いニュースです。

2 つのコードは基本的に「同じ」ことを行っていますか? フィルタリングを実行して foreach に渡すために一時的なコンテナーが作成されますか?

この件に関するヘルプは大歓迎です。ありがとう。

4

3 に答える 3

2

m_sources の場合はタイプによって異なります。

LINQ から SQL または Entity Framework へのデータ コンテキストである場合、渡す引数は Expression のインスタンスとしてコンパイルされ、解析されて SQL が作成されます (データ モデルの助けを借りて)。このプロセスにはいくつかの実際のコストがありますが、(ほとんどの場合) データベースへのラウンド トリップによって支配される可能性があります。

IEnumerable の場合、Where は次のように実装されます。

public static IEnumnerable<T> Where(this IEnumerable<T> input, Func<T, bool> predicate) {
  foreach (var v in input) {
    if (predicate(v)) {
      yield return v;
    }
  }
}

これは非常に効率的であり、遅延実行されます (したがって、ループを早期に中断すると、述語はコレクション全体に適用されません)。

于 2009-03-19T22:46:42.260 に答える
1

基本的に、はい、同じ O(n) です。

where 句は、リストをループしている間に実行されます (つまり、最初のアイテムの後でブレークすると、次のアイテムはテストされません)。

于 2009-03-19T22:43:59.223 に答える