对于平等与fn:matches()
之间的性能差异感到好奇,我运行了以下测试:
<xsl:variable name="limit" select="123456789"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:value-of
select="
count(for $i in (1 to $limit)
return
if ('m' = 'm') then
true()
else
())"/>
<xsl:value-of
select="
count(for $i in (1 to $limit)
return
if (matches('m', 'm')) then
true()
else
())"
/>
</xsl:copy>
</xsl:template>
通过Saxon HE / PE 9.7.0.15处理,<value-of>
在我的Mac上运行6.9秒。单独运行,第一个运行5.2秒,第二个运行1.8秒。这对我来说似乎不直观。为什么平等需要更长时间来评估而不是匹配?
这种差异在所有情况下都是相同的吗?也就是说,选择fn:matches()
而非=
(显然,对于字符串比较)通常可以提高性能吗?
更新:在Saxon EE下,测试加速并平衡:分别为5.1 / 2.5 / 2.5秒。它仍然留下了一个原始问题,即为什么表面上看起来更简单的操作会比更复杂的操作更长或更长。
答案 0 :(得分:1)
我怀疑你的测量是有缺陷的:通常的错误是无法允许Java预热时间,所以实际上你只是测量Java加载需要多长时间。尝试使用命令行选项-repeat:50
来查看此效果。
另一个问题是你的“=”和“匹配”调用都有常量参数,这意味着表达式将在编译时被评估一次。
Saxon实际生成的执行计划是这样的(对于两个指令值都是相同的):
<fn name="count">
<for var="i" as="xs:integer" slot="0">
<range role="in" from="1" to="123456789"/>
<true role="return"/>
</for>
</fn>
也就是说,它已将两个表达式都缩减为
count(for $i in 1 to 123456789 return true())
(这解释了为什么两者都在同一时间执行),这将是一个非常短的步骤,以进一步优化
123456789