LINQ(及其 LINQ to XML)最重要的好处之一是,链接查询的性能可以与更大、更复杂的单个查询相媲美。
链接查询是使用另一个查询作为其源的查询。 例如,在以下简单代码中, 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 作为延迟执行的迭代器实现。 这意味着,除了循环访问链接列表之外,它还会执行一些工作,例如分配迭代器对象并跟踪执行状态。 此工作可以分为两个类别:在设置迭代器时完成的工作,以及每次迭代期间完成的工作。 设置工作是少量的固定工时,每次迭代期间完成的工作与源集合中的项数成正比。
- 在
query1
中,where
语句(Where
在 Visual Basic 中)导致查询调用该 Where 方法。 此方法也作为迭代器实现。 设置工作包括实例化将引用 lambda 表达式的委托和对迭代器的常规设置。 每次迭代时,都将调用该委托以执行谓词。 在每次迭代期间进行的设置工作和其他工作,类似于沿轴线迭代时所完成的工作。 - 在
query1
中,select 子句会导致查询调用 Select 方法。 此方法的性能概要与该 Where 方法相同。 - 在
query2
中,where
子句(在 Visual Basic 中为Where
)和select
子句具有与query1
中相同的性能特性。
因此,通过 query2
的迭代与首次查询源中的项数直接成正比,换句话说,所需时间呈线性增长。
有关迭代器的详细信息,请参阅 yield。
有关将查询链接在一起的更详细教程,请参阅教程:将查询链接在一起(C#)。