XSLT document() :多次调用它会变慢吗?

Posted

技术标签:

【中文标题】XSLT document() :多次调用它会变慢吗?【英文标题】:XSLT document() : Is it slower when calling it multiple times? 【发布时间】:2011-08-22 05:54:00 【问题描述】:

UPDATE 17.Jul.2013XALAN 2.7 不缓存 document() 在请求中调用。因此,将每个需要的文档存储在 XSL 中的变量中至关重要。


我已经搜索了很长时间,但没有找到我简单问题的具体答案:

哪种方法更快或编译器足够“智能”以使两种变体相同?

注意:我使用的是 Xalan 2.7(JDK 1.6 中的默认实现):

1) 我必须读取外部 XML 中的属性:

<xsl:value-of select="document($path)/person/address/city"/>

每当我需要城市时,我都会使用上面的表达式(比如说 100 次)

2) 我没有调用 document() 100 次,而是将 XML 节点存储在一个变量中:

<xsl:variable name="node" select="document($path)"/>

然后我用了 100 次

<xsl:value-of select="$node/person/address/city"/>

哪个更快、更好,原因是什么? 谢谢!

【问题讨论】:

我也对专家的回答很感兴趣,但是,我认为,多次调用 document(path_to_doc) 的情况取决于 xslt 处理器缓存实现,在这种情况下,当文档节点存储在在任何情况下都必须加载一次的变量。 是的,我也猜想它取决于处理器的实现,但我很好奇Xalan 2.7(JDK 1.6 中的默认处理器)是如何实现的 b> 做到了。 我不是 100% 肯定的,但我认为 Xalan 不会缓存 document() 结果,但 xsltproc 会。然而,document() 参数被解释为一个 URI (see spec),因此积极的缓存将非常有意义。 好问题,+1。有关第三种更有效解决方案的解释和建议,请参阅我的答案。 使用 XALAN 2.7 测试:每个 document() 调用都将被执行并包括物理文件访问。所以至少对于 XALAN 2.7 来说,将文档存储在变量中是很有意义的。我用测试结果更新了我的问题。 【参考方案1】:

如果 XSLT 处理器不是幼稚的,那么这两个方法应该同时执行,因为文档函数在使用相同的参数调用时应该返回相同的结果,无论如何多次。

两种方法都效率不高,因为使用了//的缩写,会导致整个文档树被遍历。

我建议以下方法比正在讨论的两种方法更有效:

<xsl:variable name="vCities" select="document($pUrl)//cities"/>

那么只能参考$vCities

这样你只遍历了文档一次。

【讨论】:

+1。 Dimitre,你可以给我一个你提到的幂等规则的参考吗?我以前听说过,但很惊讶没有在 XSLT 1.0 或 2.0 规范中看到它。 btw:// 只是一个例子,不应该成为我问题的一部分,对不起!重点是document() 函数。所以我仍然不确定它是否对 XALAN 2.7 有影响! 更正的问题:它不再包含坏的例子。我删除它是因为这里的讨论应该是关于文档功能的。 @basZero -- 您可以而且必须运行自己的基准测试。我相信 Xalan 不是一个天真的非优化处理器,而且你不会通过添加自己的缓存获得太多收益。 使用 XALAN 2.7 测试:每个 document() 调用都将被执行并包括物理文件访问。所以至少对于 XALAN 2.7 来说,将文档存储在变量中是很有意义的。【参考方案2】:

里面的原理你好像明白了,这里不需要解释了。

如果你想知道 Xalan 2.7 是如何做到的,通过 Xalan 2.7 的测试会找到明确的答案,并且测试足够大。

正如@Dimitre 所指出的,由于//,这些都不一定有效,尽管一些处理器很聪明地优化了这些路径,缓解了问题。您可以通过将 city 元素保留在变量中来帮助处理器提高效率:

<xsl:variable name="city" select="(document($path)//city)[1]"/>
...
<xsl:value-of select="$city"/>

我在其中添加了[1] 以进一步优化,因为您说的是“城市”(即您只期望一个),这允许智能处理器在找到第一个city 元素后停止。

【讨论】:

讨论不是关于//,我从示例中删除了它。我将通过尝试在日志中查看每个document() 调用的请求来测试document()。但在投入时间之前,我认为这里有人会知道(从源代码中)。 有人愿意解释为什么投反对票吗?不知道是不是来自@bas 使用 XALAN 2.7 测试:每个 document() 调用都将被执行并包括物理文件访问。所以至少对于 XALAN 2.7 来说,将文档存储在变量中是很有意义的。

以上是关于XSLT document() :多次调用它会变慢吗?的主要内容,如果未能解决你的问题,请参考以下文章

如果在多个系统调用中完成,为啥 TCP 套接字会变慢?

为啥随着 innerHTML 变大,替换 innerHTML 会变慢?

当帧中没有人脸时,OpenCV 中的人脸检测器会变慢

为什么在循环访问DataTable列时第二种方法会变慢

c# / xslt - XmlResolver 未被 document() 函数调用

为啥codeigniter会变慢?