XSLT document() :多次调用它会变慢吗?
Posted
技术标签:
【中文标题】XSLT document() :多次调用它会变慢吗?【英文标题】:XSLT document() : Is it slower when calling it multiple times? 【发布时间】:2011-08-22 05:54:00 【问题描述】:UPDATE 17.Jul.2013:XALAN 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() :多次调用它会变慢吗?的主要内容,如果未能解决你的问题,请参考以下文章
为啥随着 innerHTML 变大,替换 innerHTML 会变慢?