导致XSLT性能极差的原因是什么:文本片段或优先级?

时间:2014-05-12 14:16:06

标签: performance xslt xpath saxon

我正在尝试使用XSLT进行一些清理。我想对文本片段进行一些更改,并让所有其他节点保持平静。但是,我当前的实现运行速度非常慢,并消耗大量内存。删除小模板会将运行时间从一分钟更改为几分之一秒。

这是XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:import href="../common/identity.xsl"/>

    <xsl:template match="text()" priority="100">
        <xsl:variable name="pass1" select="replace(., '(_|~)', ' ')"/>
        <xsl:variable name="pass2" select="replace($pass1, ' , ', ', ')"/>

        <xsl:variable name="final" select="$pass2"/>

        <xsl:value-of select="$final"/>
    </xsl:template>

    <xsl:template match="body/text()[1][. = ' '] | body/text()[last()][. = ' ']"
                  priority="200"/>
</xsl:stylesheet>

第一个模板替换了一些字符,第二个模板删除了第一个和最后一个文本片段,但前提是它们只包含一个空格(遗憾的是normalize-space不符合我的需要)。

这个XSLT运行速度很慢,占用大量内存。如果我删除最后一个模板,则相同的XSLT运行速度很快,并使用正常的内存量。

XSLT使用Saxon-(HE | EE)9.5.1.3在oXygen 15.2中运行。

造成这种巨大性能损失的原因是什么?一般来说是否使用了文本片段?使用优先事项?使用[1][last()]

1 个答案:

答案 0 :(得分:3)

  

使用not(follow-sibling :: text())而不是last()修复它。你能解释一下为什么或给出一些指向last()的问题?

有两种评估模式的方法:从左到右,从右到左,对应于规范5.5.3节中给出的“正式”和“非正式”语义。从右到左的方法效率更高,但它不能用于所有模式;特别是,使用位置谓词的模式很棘手。 Saxon将有效地处理大量案件,包括match="para[last()]",但对于其他一些案件,包括match="para[last()-1]"和(似乎)match="section/para[last()]",它需要缓慢而有条理的路线。我将看一下代码,看看是否可以改进。