Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 大型文档XPath查询性能_Xml_Xpath_Libxml2 - Fatal编程技术网

Xml 大型文档XPath查询性能

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

对于5 MB文档,下面的查询需要
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)。我预计它将花费大约两倍的性能(一次扫描文件更少),但没有这么大的改进。是否有任何可以转储的查询计划?