LINQ to xml查询与性能问题

时间:2012-04-28 23:09:53

标签: .net xml performance linq

我已将此LINQ写入xml查询:

Dim xd1 As XDocument = XDocument.Load("C:\doc1.xml")
Dim xd2 As XDocument = XDocument.Load("C:\doc2.xml")
Dim xd3 As XDocument = XDocument.Load("C:\doc3.xml")

Dim q = From a In xd1...<row>, b In xd2...<row>, c In xd3...<row> Where
        a.@Field1 = "pippo" AndAlso b.@Field2 = a.@RifField2 AndAlso c.@Field3 = a.@RifField3 Select
        b.@Field4, b.@Field5, c.@Field6

Dim s As String = ""
For Each a In q
    s &= a.Campo4 & " - " & a.Campo5 & " - " & a.Campo6 & vbCrLf
Next

TextBlock1.Text = s

但是这段代码需要大约5秒才能执行。当然我会改变查询,但是在调试中我已经看到了行

Dim q = From ...

执行istant,并且每个后续行都会非常快速地消失,直到“For Each”循环完成要滚动的项目并且必须退出。然后执行停止5秒,然后循环退出。

如果我写

,我会得到相同的延迟
Dim q = (From ... ).ToArray

or else if I write

Dim i As Long = q.Count

最奇怪的是,需要很长时间才能看到项目列表已完成,并且必须退出循环。详细信息:查询q只有8个项目。

您有解决我的性能问题的建议吗? Pileggi

1 个答案:

答案 0 :(得分:1)

我们在这里看到:

你有3个XML文件,假设它们各有K,L,M row元素。

您正在对所有这些元素进行cartesian product,这意味着您可以评估K * L * M可能的结果。根据K,L和M的大小,这将是非常快速的工作 - 如果每个只有1000行,那么你有10亿个可能的结果。这就是这么慢的原因。

您应首先进行过滤,以避免创建如此庞大的笛卡尔积 - 在创建笛卡尔积之前移动条件a.@Field1 = "pippo" ,这样可以显着提高性能。

例如,如果在第一个XML文件中只有10行匹配“pippo”,那么现在只有10 * 1000 * 1000可能的结果= 10百万 - 仍然很多,但只有行数的1/100在你当前的查询中。

在C#中(我不是一个VB人)就像是

var query = from a in xd1.Descendants("row").Where(x=> x.Field1 == "pippo")
            from b in xd2.Descendants("row")
            from c in xd3.Descendants("row")
            //rest of query