Как резко увеличить скорость команды xsltproc? - PullRequest
0 голосов
/ 06 июня 2019

Это формат моих данных 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. Исследовано, было ли какое-либо узкое место с аппаратным обеспечением - нет (NVMe на очень быстром 16-ти потоковом процессоре) Сначала я подумал, что чтение файла объемом 1 ГБ займет много времени.Это не так, только обработка xsltproc занимает время

Три вопроса:

  1. Эта таблица стилей XSLT выглядит оптимизированной?
  2. Есть ли способ "прекратить поиск (т.е. отменить дальнейшее чтение), когда запись найдена"?
  3. Как я могу значительно увеличить скорость выполнения команды выше?

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Что вы включаете в свои 10 секунд?Включает ли это компиляцию таблицы стилей и / или разбор / загрузку исходного документа, или это просто время выполнения XSLT?

Я бы ожидал, что построение представления дерева в памяти вашего входного файла 900 Мб - это то, чтозанимая большую часть времени (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].Но вы ищете большего, чем это.

0 голосов
/ 06 июня 2019

Предполагая, что может быть только одна строка, где Id равен 1000, вы можете сделать просто:

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

Я не знаю, приведет ли это к "значительному увеличению скорости выполнения команды".

...