【发布时间】:2011-10-04 14:28:02
【问题描述】:
有没有人测量过使用各种库以迭代或递归方式运行 equivalent similar XSL 转换的性能?我对 Java 库最感兴趣,但也欢迎其他建议。
迭代示例(有效,given 假设 //* 可能匹配该示例的相当多的元素,但不是“真实”的“精神” XSLT):
<xsl:for-each select="//*[position() <= string-length(MyData/MyValue)]">
<someTags>
<xsl:value-of select="substring(MyData/MyValue, position(), 1)"/>
</someTags>
</xsl:for-each>
递归示例(纯粹,但对于同一任务非常冗长):
<xsl:template match="data/node">
<xsl:call-template name="for-each-character">
<xsl:with-param name="data" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="for-each-character">
<xsl:param name="data"/>
<xsl:if test="string-length($data) > 0">
<someTags>
<xsl:value-of select="substring($data,1,1)"/>
</someTags>
<xsl:call-template name="for-each-character">
<xsl:with-param name="data" select="substring($data,2)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
这两个例子都取自这个问题:
XSLT for each letter in a string
注意:Stack Overflow 往往是关于 XSLT 纯度和初学者必须正确学习 XSLT 的激烈讨论的地方。虽然我不太关心“纯度”的冗长,或者相当主观的“纯度”本身,但我真的很想知道这里的性能。
【问题讨论】:
-
前段时间我问了一个类似的问题,命名模板的性能总体上略差,看看能不能找到我读的地方。
-
但是递归本身呢?实现将需要维护大型堆栈。根据每个堆栈级别上下文中的变量数量,这可能意味着很多......
-
您可能会因为这样说我而称我为纯粹主义者,但性能几乎必须是正确性的次要考虑因素。上面的迭代示例显然很可能提前结束。永远不应认为更快地获得错误结果比获得较慢的正确结果更好。
-
@empo,我猜这取决于处理器,但在任何函数式语言中,都应该安全地假设该列表不会在每次迭代时发生变化,所以实际上处理器应该只需要遍历一次。我仍然认为这是一个糟糕的解决方案,不是因为它是“反纯粹主义者”,而是因为它不可靠。
-
性能问题的最佳答案是针对示例数据运行示例代码并测量性能。命名模板似乎是尾递归的,因此通过 XSLT 处理器中的正确优化,您至少可能不会获得长字符串的 stackoverflow。虽然 for-each 可能会用完长字符串的元素。但是您知道,如果性能是问题,那么就对其进行衡量。我会以任何方式使用 XSLT 2.0:
<xsl:for-each select="string-to-codepoints(MyData/MyValue)"><someTags><xsl:value-of select="codepoints-to-string(.)"/></someTags></xsl:for-each>。
标签: performance xslt recursion iteration