私は匿名のラムダが好きです。リストから複雑な選択肢を簡潔に表現できます。 LINQも同様のことをしているので、私はそれを試してみることにしました(ついに)。LINQと匿名のラムダパフォーマンス:それぞれを使用する場合
ラムダを頻繁に使用してコレクションのサブセットを選択する人は、いつLINQを使用すればよいですか、いつラムダを使うべきですか?this oneのような質問がありますが、いずれかの方法でパフォーマンスが10〜100倍異なることが示されています。
私は匿名のラムダが好きです。リストから複雑な選択肢を簡潔に表現できます。 LINQも同様のことをしているので、私はそれを試してみることにしました(ついに)。LINQと匿名のラムダパフォーマンス:それぞれを使用する場合
ラムダを頻繁に使用してコレクションのサブセットを選択する人は、いつLINQを使用すればよいですか、いつラムダを使うべきですか?this oneのような質問がありますが、いずれかの方法でパフォーマンスが10〜100倍異なることが示されています。
LINQ評価が延期されています。 primes
との式は、コンパイラと同じです。どちらの場合でも、isOddAndNotDivisibleBy
は、何かが式の結果を評価するまで呼び出されません。この場合、c
とb
の間のToArray
が強制的に評価されます。 a
とb
の間にToArrayを追加すると、同様の時間が得られます。
比較のために、あなたは試みることができる:
var primes = (
from n in numbers
where isOddAndNotDivisibleBy(n)
select n).ToArray();
あなたのテストは同じではありません:あなたはb
とc
間ToArray()
を呼び出している、実際に実行した後にメモリを割り当てる(その後、再割り当て、その後、再割り当て)であろうあなたの質問。 a
とb
間
は、あなただけの実行、クエリを作成し、計算を実行します。 ToList()
、ToArray()
を呼び出すか、foreach
ループ経由でクエリを反復処理すると、強制的に実行されます。クエリの理解の構文から、2回目のテストに一致する一連の拡張メソッドの呼び出しに変換されるため、ほぼ同じ時間がかかります。
最後に、タイミングにはDateTime.Now
を使用しないでください。 StopWatch
を使用してください。
linqを実行しなかったので、primes .ToArray()
を実行して比較してください。実際には、これは、LINQのdeffered execution動作です、それだけでクエリを作成し、それを実行しなかった、あなたには、いくつかの機能とそれを実行ゴマのような、foreach
、ToList
、...
また、両方のあなたは物事のは、LINQで、どちらもEnumerableクラスのIEnumerableにいくつかの拡張メソッドを使用しているため、最初はクエリ構文で、もう1つはドット表記構文です。 msdn linqでそれらを見てください。
"LINQ"と呼ばれるものは、実際にはLINQクエリ構文と呼ばれます。そして、あなたが "匿名のラムダ"と呼ぶものは、実際にはLINQのメソッド構文と呼ばれます。
numbers.Where(n => isOddAndNotDivisibleBy(n))
これは、あなたが直接、前者か後者を使用している場合、あなたは同じILコードを取得することを意味します:
from n in numbers
where isOddAndNotDivisibleBy(n)
select n
が実際にコンパイルする前に、これに変換されます。重要なことは、表現ということです。
だから違いは別の場所にあるはずです。そしてそれはToArray()
です。 Where()
は怠惰です。つまり、実際に何らかの形で結果のシーケンスを反復しない限り、ほとんど何もしません。つまり、Where()
と呼ぶだけですぐに迫ってくるはずです。しかし、ToArray()
に電話すると、コレクションは実際に反復され、結果はすぐに計算されます。だから、あなたはそのような大きな違いを見るのです。
EDIT:他の上に1つの構文を使用する理由:変更された質問への
?主に、より読みやすいものを選択します。
は、クエリ構文(First()
、Aggregate()
、Concat()
Zip()
、インデックスを紹介過負荷、...)を使って表現することができないいくつかのメソッドとオーバーロードがあります。しかし、クエリの一部分と残りの部分にそれぞれ1つの構文を使用できます。
また、構文構文を使用して簡単に表現できない強力なクエリ構文の1つがあります。 let
句を使用する場合。
しかし、2つの構文の間にパフォーマンスの違いはありません。これらの例
LINQメソッド構文?私はあなたがドット表記法、またはメソッド連鎖構文を意味すると思います。 –
それはMSがそれを呼んでいるものです:http://msdn.microsoft.com/en-us/library/bb397947.aspx – svick
Microsoftはhttp://msdn.microsoft.com/en-us/library/bb308959 .aspxはドット表記法を示しています。メソッドのシンタックスも意味があります。メソッド連鎖パターン(http://en.wikipedia.org/wiki/Method_chainingを参照)があります。表記:)メソッド構文ではありません。 –
の両方が、確かに、同じLINQ はを照会しますが、異なる構文砂糖とされています。
クエリとはどういう意味ですか? LINQクエリは、mySequence.Where(i => i > 5)
または(from item in mySequence where item > 5)
で作成するかどうかにかかわらず、格納される唯一のデータはシーケンスを列挙できることです。つまり、あなたの最初のクエリは評価されません - あなたToArray
またはToList
またはToDictionary
またはforeach
、シーケンスはその後、あなたはこのような巨大なパフォーマンスのギャップを持っている理由である、評価され
。これまで
最初のコードは '.ToArray()'を除いて2番目のコードと同じようにコンパイルされます。 – SLaks
また、DateTime.Nowはこの種のベンチマークには十分正確ではありません。 – driis
私はそこに顕著な意味の違い、ToArray呼び出しがあると思います。あなたがLINQの表現にそれを貼り付けたら、私は2つが近いと思うでしょう。 – heisenberg