28

我已经使用以下两种方法解析了 XML...

  • 使用对象模型和 XPath 查询解析 XmlDocument。
  • XSL/T

但是我从来没用过...

  • .Net 3.5 新增的 Linq Xml 对象模型

谁能告诉我这三种选择之间的比较效率?

我意识到特定的用法会是一个因素,但我只是想要一个粗略的想法。例如,Linq 选项是否比其他选项慢很多?

4

4 回答 4

44

查询 XML 文档的绝对最快方法是最难的:编写一个使用 XmlReader 处理输入流的方法,并让它在读取节点时对其进行处理。这是将解析和查询组合到单个操作中的方法。(仅仅使用 XPath 不会这样做;XmlDocument 和 XPathDocument 都在它们的 Load 方法中解析文档。)如果您正在处理非常大的 XML 数据流,这通常是一个好主意。

您描述的所有三种方法的执行方式都相似。XSLT 有很多空间可以成为最慢的,因为它可以让您将 XPath 的低效率与模板匹配的低效率结合起来。XPath 和 LINQ 查询本质上都做同样的事情,即通过 XML 节点的可枚举列表进行线性搜索。我希望 LINQ 在实践中稍微快一些,因为 XPath 在运行时解释,而 LINQ 在编译时解释。

但总的来说,您编写查询的方式对执行速度的影响要比您使用的技术大得多。

无论您使用 XPath 还是 LINQ,针对 XML 文档编写快速查询的方法都是相同的:制定查询,以便在执行期间访问尽可能少的节点。使用哪种技术并不重要:检查文档中每个节点的查询将比仅检查其中一小部分节点的查询运行得慢得多。您这样做的能力比其他任何事情都更依赖于 XML 的结构:具有可导航元素层次结构的文档通常比其元素都是文档元素的子元素的文档要快得多。

编辑:

虽然我很确定我是对的,查询 XML 的绝对最快方法是最难的,但真正最快(也是最难)的方法不使用XmlReader; 它使用状态机直接处理来自流的字符。就像用正则表达式解析 XML 一样,这通常是一个糟糕的主意。但它确实为您提供了以速度交换功能的选项。通过决定不处理您的应用程序不需要的那些 XML 片段(例如名称空间解析、字符实体的扩展等),您可以构建一些比搜索更快的字符流的东西XmlReader。我可以想到这甚至不是一个坏主意的应用程序,尽管我想不出很多。

于 2008-10-08T19:32:38.037 回答
3

LinqToXml 查询对 IEnumerable 合约起作用......它的大部分操作都是 O(N),因为它们需要对 IEnumerable 进行迭代。

如果您开始的是一个包含 xml 的字符串,为了在 Linq 中使用它,您需要使用XElement.Parse将其解析为完整的对象图,然后迭代其中的部分(过滤它,例如例子)。

我对 XPath 的理解是它会在解析时进行过滤,从性能的角度来看,这可能是非常有利的。不需要构造完整的对象图。

于 2008-10-08T14:23:08.957 回答
2

我还没有实际测试过,但 Linq 主要是编译器代码生成类型功能,因此它应该与使用 XmlDocument 和 XPath 查询相当。

Linq 的主要价值在于它提供了查询语句的编译时验证,而 XPath 和 XSLT 都无法提供。

我认为如果性能是一个问题,您的决定将基于手头的任务。例如,使用单个 XPath 查询从 XML 文档中检索单个值可能最快,但使用 XSLT 将 XML 数据转换为 HTML 页面会更快。

于 2008-10-08T14:15:55.507 回答
2

如果您想要真正快速的 XML 处理(读取),您应该考虑使用 XmlReader 不幸的是实现有点困难。

还有一种方法可以结合 XmlReader 来实现 LINQ 解决方案,这样您就可以轻松使用 LINQ。此外,您可以获得比 XmlDocument/XPath 更好的性能。

有关这方面的更多信息,请参阅以下链接。 http://blogs.msdn.com/xmlteam/archive/2007/03/24/streaming-with-linq-to-xml-part-2.aspx

另外我认为,如果您只使用 XmlDocument/XPath 处理小型 XML 文件,这不会是性能问题。

于 2009-05-15T11:06:48.930 回答