2009-08-04 9 views
4

オブジェクトコレクションに対するLINQクエリで、正確に何が起こっていますか?構文的な砂糖だけであるか、効率的なクエリをより多く作成しているのですか?LINQパフォーマンス

答えて

2

文法的な砂糖だけです。魔法は必要ありません。

"longhand"、C#などで同等のコードを書くことができます。これは同じコードを実行します。

(もちろんコンパイラは効率的なコードを生成するのに良い仕事をするでしょう。そのため、作成するコードは、あなたが書いたコードよりも効率的です。そのコードを書いてください)。

12

あなたはクエリ式の意味か、クエリがその場で何をしていますか?

クエリ式は「通常の」C#に展開されます。例:これの正確な意味はもちろんのsourceの種類によって異なります... LINQのオブジェクトに、それは一般的にIEnumerable<T>と実装

var query = source.Where(x => x.Name == "Fred") 
        .Select(x => x.Age); 

var query = from x in source 
      where x.Name == "Fred" 
      select x.Age; 

がに変換され拡張メソッドが有効になりますが、拡張メソッドの別のセットになる可能性があります。 (LINQ to SQLは、例えば、Queryable拡張メソッドを使用します。)

を今、オブジェクトにLINQを使用して、我々あるを想定...拡張メソッドを拡張した後、上記のコードは次のようになります。

var query = Enumerable.Select(Enumerable.Where(source, x => x.Name == "Fred"), 
           x => x.Age); 

次に、SelectWhereの実装が重要になります。

public static IEnumerable<T> Where<T>(this IEnumerable<T> source, 
             Func<T, bool> predicate) 
{ 
    foreach (T element in source) 
    { 
     if (predicate(element)) 
     { 
      yield return element; 
     } 
    } 
} 

public static IEnumerable<TResult> Select<TSource, TResult> 
    (this IEnumerable<TSource> source, 
    Func<TSource, TResult> selector) 
{ 
    foreach (TSource element in source) 
    { 
     yield return selector(element); 
    } 
} 

次の私はここに入るが、私はarticle aboutを持っていません。ステートマシンに変換する反復子ブロックの拡大があります:エラーチェックを残して、彼らはこのような何かです。

最後に、ラムダ式を追加のメソッド+適切なデリゲートインスタンスの作成(または、呼び出されるメソッドのシグネチャに応じて式ツリー)に変換します。

だから、基本的にLINQは、C#の巧妙な機能の多く使用しています。一般的な方法 用(デリゲートのインスタンスと式ツリーに)

  • ラムダ式の変換
  • 拡張メソッド
  • 型推論を
  • イテレータブロック
  • 匿名型(投影用)
  • 多くの場合、ローカル変数の暗黙の型
  • クエリ式の変換

しかし、個々の操作は非常に簡単です - 彼らは、インデックス作成を行わないなどが参加し、グループをハッシュテーブルを使用して行われているが、のような簡単なクエリ"where"はちょうど線形です。 LINQ to Objectsは通常、データをフォワードのみの読み取り可能なシーケンスとして扱うことを忘れないでください。バイナリ検索のようなことはできません。

通常、手書きクエリはLINQ to Objectsよりわずかに高速ですが、抽象レイヤーが少ないため、通常は読みにくく、パフォーマンスの差異は通常有意ではありません。

これまでと同様にパフォーマンスに関する質問があります。

+0

私はそれが舞台裏で何を意味するのかを意味しました。たとえば、私はオブジェクトコレクションを持っています。私はコレクション全体を反復し、各オブジェクトで必要な値のプロパティをチェックするか、LINQを使うことができるForループを書くことができます。私が読んだことによると、多くの場合、LINQが高速になるようです。私の質問はなぜそれが速く、どのようにルックアップをやっているのですか? – Crios

+0

LINQは通常同等のコードより速くはありませんが、たとえば、インデックス付き検索を提供する他のプロジェクトがあると思います。 LINQの高速化が期待される具体的な例を挙げることができれば、参考になるでしょう。 –

3

パフォーマンスがさらに必要な場合は、i4o - オブジェクトのインデックスを試してみることを検討してください。 LINQがクエリを高速化するために使用する、大規模なコレクション(100,000以上の行と考える)用のメモリ内オブジェクトを構築します。この作業を行うには多くのデータが必要ですが、改善は印象的です。

http://www.codeplex.com/i4o

関連する問題