Xml 大型文档XPath查询性能
对于5 MB文档,下面的查询需要Xml 大型文档XPath查询性能,xml,xpath,libxml2,Xml,Xpath,Libxml2,对于5 MB文档,下面的查询需要libxml23秒的时间进行计算。我能做些什么来加快速度吗?我需要生成的节点集进行进一步处理,因此无count,等等 谢谢 descendant::text() | descendant::* [ self::p or self::h1 or self::h2 or self::h3 or self::h4 or self::h5 or self::h6 or self::dl or self::dt or self::dd or self::ol or self
libxml2
3秒的时间进行计算。我能做些什么来加快速度吗?我需要生成的节点集进行进一步处理,因此无count
,等等
谢谢
descendant::text() | descendant::*
[
self::p or
self::h1 or
self::h2 or
self::h3 or
self::h4 or
self::h5 or
self::h6 or
self::dl or
self::dt or
self::dd or
self::ol or
self::ul or
self::li or
self::dir or
self::address or
self::blockquote or
self::center or
self::del or
self::div or
self::hr or
self::ins or
self::pre
]
编辑:
使用Jens Erat建议的
后代::节点()[self::text()或self::p或…
(参见接受的答案)大大提高了速度;从原来的2.865330s提高到了完美的0.164336s。是否启用了--with threads选项来编译libxml2?如果启用了--with threads选项,最简单的方法就是使用更快的处理器和更多的内核来解决问题。是否启用--with threads选项来编译libxml2如果是这样的话,最简单的方法就是使用一个速度更快、内核更多的处理器来解决问题您的查询相当于
(descendant::text() | descendant::p
| descendant::h1 | descendant::h2 | descendant::h3 | descendant::h4 | descendant::h5 | descendant::h6
| descendant::dl | descendant::dt | descendant::dd | descendant::ol | descendant::ul | descendant::li
| descendant::dir | descendant::address | descendant::blockquote | descendant::center
| descendant::del | descendant::div | descendant::hr | descendant::ins | descendant::pre
)
但我无法测量其速度的任何差异。您的查询相当于
(descendant::text() | descendant::p
| descendant::h1 | descendant::h2 | descendant::h3 | descendant::h4 | descendant::h5 | descendant::h6
| descendant::dl | descendant::dt | descendant::dd | descendant::ol | descendant::ul | descendant::li
| descendant::dir | descendant::address | descendant::blockquote | descendant::center
| descendant::del | descendant::div | descendant::hr | descendant::ins | descendant::pre
)
但是我无法测量其速度上的任何差异。如果没有任何文档进行基准测试,那么进行基准测试是非常困难的 优化的两个想法:
- 使用尽可能少的
轴步骤。这些步骤很昂贵,可能您可以加快一点速度。您可以将子代::
和元素测试结合起来,如下所示:text()
并扩展到所有元素(为了更好的可读性,我保持查询的简短)descendant::node()[self::text() or self::h1 or self::h2]
- 使用字符串测试而不是节点测试。它们可能更快(可能不是,请参阅答案的注释)。当然,您需要保留
测试text()
descendant::node()[self::text() or local-name(.) = 'h1' or local-name(.) = 'h2']
如果您经常查询同一个文档,请考虑使用本地XML数据库,如BaseX、eXist DB、Zorba、Marklogic等(前三个是免费的)。它们将索引放在您的数据上,应该能够更快地提供结果(并支持XPath 2.0/XQuery,这使开发变得更容易)。它们都有一大套编程语言的API。在没有任何文档的情况下进行基准测试是非常困难的 优化的两个想法:
- 使用尽可能少的
轴步骤。这些步骤很昂贵,可能您可以加快一点速度。您可以将子代::
和元素测试结合起来,如下所示:text()
并扩展到所有元素(为了更好的可读性,我保持查询的简短)descendant::node()[self::text() or self::h1 or self::h2]
- 使用字符串测试而不是节点测试。它们可能更快(可能不是,请参阅答案的注释)。当然,您需要保留
测试text()
descendant::node()[self::text() or local-name(.) = 'h1' or local-name(.) = 'h2']
如果您经常查询同一个文档,请考虑使用本地XML数据库,如BaseX、eXist DB、Zorba、Marklogic等(前三个是免费的)。它们将索引放在您的数据上,应该能够更快地提供结果(并支持XPath 2.0/XQuery,这使开发变得更容易)。它们都有大量编程语言的API。我希望在这里看到您对不同方案的基准测试的一些反馈。@JensErat我已经测量了它并编辑了我的问题。非常感谢您的建议。我希望在这里看到您对不同方案的基准测试的一些反馈。@JensErat我已经测量了它并编辑了我的问题。非常感谢你的建议。我想它会比文档(需要|可能)更快,而不是更慢被扫描多次,每个
子代一步。我不确定libxml2的优化有多聪明。这比我问题中使用的原始查询慢得多。请参阅@JensErat的答案。我猜它会比文档(需要|可能)的速度慢得多,而不是更快被扫描多次,每个子代一步。我不确定libxml2的优化有多聪明。这比我问题中使用的原始查询慢得多。请参阅@JensErat的答案。libxml2不使用线程来加速XPath表达式的计算。libxml2不使用线程来加速XPath表达式的计算XPath表达式。我熟悉libxml2中XPath引擎的一些内部结构,并使用local-name()
代替NodeTest当然更慢。不过,你的第一个建议应该会带来可测量的加速。我刚刚在一个测试文档上尝试了你的第一个建议,结果加速了15倍。哇,这比我预期的快了14倍。@nwellnhof你猜为什么会这样吗?主要是因为libxml2对结果进行排序一个联合,以确保节点在文档中的顺序。对我来说仍然很奇怪,它所要做的就是执行合并排序的合并步骤,即O(n)。我预计它需要大约两倍的性能(一次扫描文件更少),但这并不是一个很大的改进。是否有任何类型的查询计划可以转储?我熟悉libxml2中XPath引擎的一些内部结构,并使用local-name()
代替NodeTest当然更慢。不过,你的第一个建议应该会带来可测量的加速。我刚刚在一个测试文档上尝试了你的第一个建议,结果加速了15倍。哇,这比我预期的快了14倍。@nwellnhof你猜为什么会这样吗?主要是因为libxml2对结果进行排序合并以确保节点按文档顺序排列。对我来说仍然很奇怪,它所要做的只是执行合并排序的合并步骤,即O(n)。我预计它将花费大约两倍的性能(一次扫描文件更少),但没有这么大的改进。是否有任何可以转储的查询计划?