次の方法で共有


チェーンクエリのパフォーマンス (LINQ to XML)

LINQ (および LINQ to XML) の最も重要な利点の 1 つは、チェーンされたクエリが、チェーンされたクエリよりも大きく複雑な 1 つのクエリと同様に実行できることです。

チェーン クエリは、別のクエリをソースとして使用するクエリです。 たとえば、次の単純なコードでは、 query2 のソースとして query1 があります。

XElement root = new XElement("Root",
    new XElement("Child", 1),
    new XElement("Child", 2),
    new XElement("Child", 3),
    new XElement("Child", 4)
);

var query1 = from x in root.Elements("Child")
             where (int)x >= 3
             select x;

var query2 = from e in query1
             where (int)e % 2 == 0
             select e;

foreach (var i in query2)
    Console.WriteLine("{0}", (int)i);
Dim root As New XElement("Root", New XElement("Child", 1), New XElement("Child", 2), New XElement("Child", 3), New XElement("Child", 4))

Dim query1 = From x In root.Elements("Child") Where CInt(x) >= 3x

Dim query2 = From e In query1 Where CInt(e) Mod 2 = 0e

For Each i As var In query2
    Console.WriteLine("{0}", CInt(i))
Next

この例では、次の出力が生成されます。

4

このチェーン クエリは、リンクされたリストを反復処理する場合と同じパフォーマンス プロファイルを提供します。

  • Elements軸のパフォーマンスは、リンクリストを反復処理する場合と基本的に同じです。 Elements は、遅延実行を持つ反復子として実装されます。 これは、反復子オブジェクトの割り当てや実行状態の追跡など、リンクされたリストの反復処理に加えて、いくつかの作業を実行することを意味します。 この作業は、反復子の設定時に実行される作業と、各イテレーション中に実行される作業の 2 つのカテゴリに分けることができます。 セットアップ作業は少量の固定作業であり、各イテレーション中に実行される作業は、ソース コレクション内の項目の数に比例します。
  • query1では、where句 (Visual Basic のWhere) により、クエリによって Where メソッドが呼び出されます。 このメソッドは反復子としても実装されます。 セットアップ作業は、ラムダ式を参照するデリゲートのインスタンス化と、反復子の通常のセットアップで構成されます。 反復処理のたびに、デリゲートが呼び出されて条件が実行されます。 各イテレーションの間に行われるセットアップ作業と作業は、軸の反復処理中に実行される作業と似ています。
  • query1では、select 句によってクエリが Select メソッドを呼び出します。 このメソッドのパフォーマンス プロファイルは、 Where メソッドと同じです。
  • query2では、where句 (Visual Basic のWhere) と select 句の両方に、query1と同じパフォーマンス プロファイルがあります。

したがって、 query2 を通じた反復は、最初のクエリのソース内の項目数 (つまり、線形時間) に直接比例します。

反復子の詳細については、「 yield」を参照してください。

クエリの連結に関するより詳細なチュートリアルについては、「 チュートリアル: クエリを連結する (C#)」を参照してください。