web-dev-qa-db-ja.com

.NETでのLINQとラムダ式の効率とパフォーマンスとは何ですか?

.Net 3.5とVS 2008を1か月以上使用しています。ほとんどの.Net開発者と同様に、私は.Net 1.0&2.0およびVS 2005での長年の経験から進化しました。つい最近、 リスト内のアイテムをLINQ で検索し、 LambdaまたはLINQ を使用して、クラスインスタンスを別のインスタンスのリストに変換またはマップし、 LambdaまたはLINQ を使用して、クラスのリストを別のクラスのリストに変換またはマップします。

LambdaとLINQははるかにシンプルで読みやすく、非常に強力に見えます。 .Netコンパイラーは、これらの機能を実現するために多くのコードを生成する必要があります。したがって、同じ結果を達成するための「古い」方法をすでに知っているので、新しい構文に切り替えるのには少し躊躇しています。

私の質問は、ラムダとLINQの効率とパフォーマンスについてです。たぶん、ラムダ式はほとんどインライン関数です。その場合、ラムダは大丈夫だと思います。 LINQはどうですか?

議論をLINQ-to-Objects LINQ-to-SQL(LINQ-to-SQL)に限定しましょう。コメント、比較、経験はありますか?

38
David.Chu.ca

ここで十分な答えは1つではありません。

LINQには多くの用途と実装があり、コードの効率に多くの影響を与えます。

私たちの手元にあるすべてのテクノロジーと同様に、LINQは悪用されたり悪用されたりする可能性があります。また、それを区別する機能と適切な使用法は、知識という1つの要素にのみ依存しています。

だから私があなたに与えることができる最良のアドバイスは、LINQが実際にどのように実装されているかを読んで読むことです。

チェックインする必要のあるものは次のとおりです。

そしていつものように、効率の問題を見るとき、唯一の安全なアプローチは測定することです。 LINQを使用して、単一の、知っている、ことを行い、代替案を作成するコードを作成し、両方を測定して、改善を試みます。推測して仮定すると、悪い結果につながるだけです。

34

技術的に最速の方法は、すべての特徴点を自分で制御することです。 ここにいくつかのパフォーマンステストがあります 。 foreachキーワードとForEach LINQコンストラクトは、forを使用して手続き型コードを作成するよりもはるかに遅いことに注意してください。

ただし、コンパイラーは改善される可能性があり、今後も改善されます。コードのプロファイルを作成し、問題のある領域を最適化できます。通常、余分なナノ秒が必要でない限り、コードを読みやすくする表現力の高い機能を使用することをお勧めします。

6
George Mauer

LINQクエリの場合、「新しい構文」で生成されるIL(コード)は、基本的に、EnumerableおよびQueryableによって提供される拡張メソッドを直接呼び出すことと同じです。

5
Michael Morton

時期尚早に最適化しないでください。読みやすさを向上させ、アプリケーションのプロファイルを後で作成する場合は、Linqと新しい拡張メソッドを自由に使用します。

ほとんどの場合、Linqと単純なforループの使用の違いはまったく関係ありません。コードの保守性の向上は、数ミリ秒の価値があるはずです。 Linqは、ステートマシンとして実装されている列挙子で動作するため、遅くなる可能性があります。したがって、単純なfor(...)ループはより高速になります。

Lasse V. Karlsensのアドバイスに従い、リンクリストに http://www.davesquared.net/2009/07/enumerables-linq-and-speed.html を追加することをお勧めします。

3
sbreitzke

LINQクエリとLambda式の間にパフォーマンスの違いはありません。

パフォーマンスの問題を調べる前に、.NetでLINQ機能(Lambda、LINQクエリの両方)がどのように機能するかを完全に理解する必要があります。

基本的に、LINQクエリとLambda式のどちらでも使用できます。

LINQクエリ

  1. これは、高レベルで読み取り可能なクエリです。

  2. 同等のラムダ式に変換され、ノードとして式ツリーに追加されたラムダ式。ラムダ式の構造を作る式ツリー。これはコンパイラによって行われます。

  3. クエリプロバイダーは、式を調べ(式ツリーのノードとして追加)、同等のSQLクエリ演算子を生成するため、実行時に形成される同等のSQLクエリ。

  4. 戻り値の型:結果セット(IEnumerable)。

ラムダ式

  1. 式/ステートメントのセットであり、デリゲート/式ツリーを作成します。引数として関数に渡すことができます。

  2. LINQクエリのようなすべてのLINQメソッドをサポートします。 (場所、選択、カウント、合計など)

  3. ラムダ式の構造を形成する式ツリーが形成されます。これはコンパイラによって行われます。

  4. クエリプロバイダーは式(式ツリー)を調べ、実行時に同等のSQLクエリを生成します。

  5. 戻り値の型:Delagate/Expression Tree

どちらがベストですか?

以上の点を見ると、LINQ(クエリ、ラムダ)を理解できます。

LINQクエリの利点-読み取り可能です。

ラムダの利点

  1. Lambdaはデリゲートを作成し、デリゲートを使用することで、入力パラメーターを渡してさまざまな入力パラメーターの結果を取得できるため、利点があります。さまざまな条件でさまざまなクエリを記述する必要もありません。

  2. Lambda式と式ツリーを使用して動的クエリを作成できます。

  3. ステートメントの結果を引数としてメソッドに渡したい場合は、ラムダ式を使用できます。

  4. 式は短くなります。

したがって、ラムダ式はLINQクエリを介した開発に最適です。

2
Balaji Umapathy

場合によっては、LINQは他の方法よりも速くなくても同じくらい高速ですが、他の場合は遅くなることがあります。私たちはlinqに変換したプロジェクトに取り組んでいます。データの検索は高速ですが、2つのテーブル間のデータのマージははるかに低速です。少しオーバーヘッドがありますが、ほとんどの場合、速度の違いがプログラムに大きな影響を与えることはありません。

2
ecspot