句は、舞台裏でやって「」オブジェクトへのLINQとは何ですか?
-
21-08-2019 - |
質問
私は、コードのこの部分を交換しました。
foreach( var source in m_sources )
{
if( !source.IsExhausted )
{
....
}
}
このいずれかでます:
foreach( var source in m_sources.Where( src => !src.IsExhausted ) )
{
...
}
これでコードは(私には)良く見えるが、私は本当にここ何が起こっているのかと思いまして。私はこのときのパフォーマンスが心配だし、このフィルタを適用することは、コンパイラの魔法のいくつかの種類が場所を取ることを意味するならば、それは悪いニュースがあると思います。
2つのコードは基本的に「同じ」ことをやっていますか?一時的なコンテナは、私のforeachに渡すその後、フィルタリングを行うために作成されていますか?
、件名に任意のヘルプはかなり理解されるであろう。おかげます。
解決
yield return
キーワードとラムダは、コンパイル時と実行時に余分なオブジェクトの割り当てに隠されたクラスの作成を伴わない、とあなたの背景がCまたはC ++であれば、それはパフォーマンス心配するだけで自然なことです。
ナチュラル、間違った!
他のヒント
これはm_sourcesかの種類によって異なります。
それはSQLやEntity FrameworkのLINQへのデータコンテキストの場合は、あなたが渡す引数は、Expressionのインスタンスとしてコンパイルされ、(データモデルの助けを借りて)SQLを作成するために解析されます。そここの過程でいくつかの本当のコストがありますが、おそらく(ほとんどの場合)、データベースへのラウンドトリップによって支配される。
それはその後、IEnumerableをどこほとんどとして実装されている場合:
public static IEnumnerable<T> Where(this IEnumerable<T> input, Func<T, bool> predicate) {
foreach (var v in input) {
if (predicate(v)) {
yield return v;
}
}
}
はかなり効率的で、(あなたがループから抜け出す場合こんなに早く述語がコレクション全体に適用されません)なまけ行います。
基本的に、はい、それは同じ、O(n)のです。
あなたのリストをあなたループしながら、句が(あなたが最初の項目の後に壊れた場合、すなわち、以下の項目がテストされません)実行されます。このザ・
所属していません StackOverflow