如何大幅提高xsltproc命令的速度?

时间:2019-06-06 05:23:00

标签: xml performance xslt xslt-1.0

这是我的XML数据的格式:

<?xml version="1.0" encoding="utf-8"?>
<rowdata>
  <row Id="1" type="1" data="text" ... />
  <row Id="2" type="2" data="text" parent="1" ... />
  <row Id="3" type="1" data="text" ... />
  <row Id="4" type="1" data="text" ... />
  <row Id="5" type="2" data="text" parent="4" ... />
  ...

这是我的XSL工作表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/rowdata">
  <xsl:for-each select="row">
    <xsl:if test="@Id = 10000">
      <xsl:value-of select="@data"/><xsl:text>&#xa;</xsl:text>
    </xsl:if>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

事实:

  1. 我无法更改XML数据
  2. 我可以更改XSL工作表
  3. XML数据中有很多行
  4. 每个选择器只能匹配一行

问题:

  1. 此命令:xsltproc input.xls input.xml非常慢。单次执行需要大约10秒的时间(很多次需要执行)

已经尝试:

  1. 研究了是否可以使xsltproc更快(多线程运行)-它不能
  2. 研究硬件是否存在瓶颈-否(在非常快的16线程CPU上为NVMe) 起初,我认为读取1GB的文件会花费很长时间。并非如此,只是xsltproc处理需要时间

三个问题:

  1. 此XSLT样式表看起来是否经过优化?
  2. 是否有办法“在找到记录后终止搜索(即取消进一步的阅读)”?
  3. 如何大大提高上面命令的速度?

2 个答案:

答案 0 :(得分:1)

10秒内您包括什么?这是否包括编译样式表和/或解析/加载源文档,还是纯粹是XSLT执行时间?

我希望大部分时间都在花900Mb输入文件的内存树表示形式进行构建(10秒对于该操作来说将是非常快的)。如果您需要多次运行样式表,那么提高性能的最佳方法将是只构建一次源树并重新使用它。但是您将无法直接从命令行运行。

原则上,您可以使用按键来加速这种样式表:

<xsl:key name="k" match="row" use="@Id"/>
<xsl:template match="/rowdata">
  <xsl:value-of select="key('k', 10000)/@data"/>
</xsl:template>

但是,只有在您可以确保键索引仅构建一次,然后重复使用的情况下,这才起作用。在这一阶段,我无法告诉您这在xsltproc中的工作方式,因为它们都是特定于处理器的。

您只需添加谓词[1],即可在第一次匹配后终止搜索。但是,您正在寻找比这更大的收益。

答案 1 :(得分:0)

假设Id为1000的情况下只能存在一行,您可以执行以下操作:

<xsl:template match="/rowdata">
    <xsl:value-of select="row[@Id=1000]/@data"/>
</xsl:template>

我不知道这是否会“极大地提高命令速度”。