Как можно использовать xsl: аккумулятора для некоторой реализации кэширования внутри функции xsl: для ускорения оценки? - PullRequest
0 голосов
/ 06 апреля 2020

Перед чем-либо

Привет! По промышленным причинам я не могу предоставить реальные примеры кода, но я думаю, что мой вопрос довольно прост без него. Я мог бы тренироваться с "фиктивным" кодом, но это займет больше времени, чем необходимо. Кстати, посмотрите на мой предыдущий пост , который может дать вам приблизительное представление о входных документах и ​​моем проблема.

Контекст

Я работаю над входными xml документами, в которых "грамматика" включает в себя некоторый "компонентный / составной" тип отношений с общей идеей - объявлять объекты как:

- "A is a component"
- "B is a composite using A"
- "C is a composite using B"
- "D is a composote using C"

Такие отношения между сущностями "A, B" переносятся по атрибуту, содержащему ID / IDREF. Демонстрацию, приведенную в моего предыдущего поста , можно использовать для иллюстрации, если хотите.

Вариант использования для XSL

XSL используется в этом контексте с уже полностью работающее преобразование предварительное формирование "интенсивного сопоставления критериев" среди входных узлов и создание единого выходного документа, который "суммирует" результаты этих оценок критериев на всех соответствующих узлах.

  • , поскольку природа соответствия критерия включает в себя обход упомянутых отношений между узлами, поиск может включать рекурсивность, поэтому я реализовал оценку этих критериев в функциях, скажем,
<xsl:function name="my:criterion" ...>
  • так, для данного В узле A возможно, что во время обхода дерева критерий на A оценивается несколько раз (но каждый критерий определен c по своей природе!). Во время работы преобразование может привести к серии вызовов следующим образом (псевдокод)
call my:criterion(A);
...
call my:criterion(B);
     | call my:criterion(A)
...
call my:criterion(C);
     |call my:criterion(B);
           | call my:criterion(A) 

call my:criterion(D);
     |call my:criterion(C);
           | call my:criterion(B)
                  | call my:criterion(A)

and so on ...

Проблематично c

Даже если преобразование уже дает ожидаемые результаты , я хочу немного «глубже» понять и улучшить производительность с точки зрения времени выполнения. Один из способов оптимизировать преобразование заключался бы в реализации некоторого «кэширования результатов» во время оценки критерия, чтобы избежать нескольких оценок для одного и того же элемента (помните: функции критерия детерминированы c по природе ) I Я думал, что xsl: аккумулятор может помочь, но я только что открыл их, и я не уверен, что смогу использовать их в рамках функции.

Ожидания

  • Спасибо за то, что предоставили несколько советов о том, как реализовать кэширование вызовов функций и как xsl: аккумулятор может / не может быть полезен для этой цели.

  • Спасибо, что не слишком быстро на "пожалуйста, предоставьте пример кода" легко ответить. Я могу думать о «фиктивном» коде, чтобы работать с ним, но время, которое требуется для работы с этим фиктивным кодом, не стоит, если быстрый ответ можно получить без них!

1 Ответ

1 голос
/ 06 апреля 2020

Я думаю, что функция, которую вы ищете:

<xsl:function ... cache="yes">

Это эффективно превращает функцию в «функцию памятки», которая запоминает результаты предыдущих вызовов и извергает их, если функция вызывается повторно с те же аргументы.

В некоторых ограниченных случаях xsl:accumulator может использоваться для достижения того же эффекта, но только (a), когда это функция одного узла, и (b) функция может быть вычислена исключительно путем ссылки на предыдущие узлы в том же документе. Это потому, что xsl:accumulator предназначен в первую очередь для облегчения потоковой передачи.

...