Sdílet prostřednictvím


Výkon zřetězených dotazů (LINQ to XML)

Jednou z nejdůležitějších výhod LINQ (a LINQ to XML) je to, že zřetězený dotazy můžou provádět i jeden dotaz, který je větší a složitější než zřetězený dotazy.

Zřetězený dotaz je dotaz, který jako zdroj používá jiný dotaz. Například v následujícím jednoduchém kódu query2query1 jako zdroj:

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

Tento příklad vytvoří následující výstup:

4

Tento zřetězený dotaz poskytuje stejný profil výkonu jako iterace prostřednictvím propojeného seznamu.

  • Elements osa má v podstatě stejný výkon jako iterace prostřednictvím spojovaného seznamu. Elements se implementuje jako iterátor s odloženým spuštěním. To znamená, že vedle iterace přes propojený seznam provádí ještě další činnosti, jako je přidělení objektu iterátoru a sledování stavu provádění. Tuto práci lze rozdělit do dvou kategorií: práce, která se provádí v době, kdy je iterátor nastaven, a práce, která se provádí během každé iterace. Práce na nastavení představuje malé a pevně stanovené množství práce a práce provedená během každé iterace je úměrná počtu položek ve zdrojové kolekci.
  • V query1, klauzule where (Where v jazyce Visual Basic) způsobí, že dotaz zavolá metodu Where . Tato metoda je také implementována jako iterátor. Konfigurační práce se skládají z vytvoření instance delegáta, který bude odkazovat na výraz lambda, spolu s běžným nastavením iterátoru. Při každé iteraci je delegát volán ke spuštění predikátu. Nastavení a práce provedené během každé iterace se podobají práci, která se provádí při iteraci přes osu.
  • Klauzule query1select způsobí, že dotaz zavolá metodu Select . Tato metoda má stejný profil výkonu jako metoda Where.
  • V query2 mají jak klauzule where (Where ve Visual Basicu), tak klauzule select stejný profil výkonu jako v query1.

Iterace query2 je tedy přímo úměrná počtu položek ve zdroji prvního dotazu, jinými slovy lineárního času.

Další informace o iterátorech najdete v tématu yield.

Podrobnější kurz o zřetězování dotazů najdete v tématu Kurz: Zřetězování dotazů dohromady (C#).