XQuery: лениво оцениваются ли импортированные переменные?

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

Тем не менее, содержание некоторых из них являются вычислительно дорогими выражениями. Как функции, они, очевидно, будут оцениваться только при вызове. Но как переменные я не уверен, будут ли они автоматически оцениваться при импорте библиотечного модуля.

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

Однако не было бы проблем, если бы импортированные переменные лениво оценивались: я мог импортировать библиотечный модуль для любого запроса, зная, что эти дорогие переменные оцениваются только в том случае, если они фактически используются главным модулем.

Я знаю, что это просто вопрос письма prefix:myImportedFunction() против $prefix:myImportedVariable, но это неопределенность, которую я хотел бы рассеять.

Я считаю, что это поведение зависит от реализации. Меня особенно интересует поведение в BaseX и Saxon-HE. Они лениво оценивают импортированные переменные?

2 ответа

Решение

Саксон обычно использует ленивую оценку для глобальных переменных. Исключением является то, что включена трассировка во время выполнения (что может быть сделано, если вы отлаживаете в IDE); затем он переключается на готовую оценку, чтобы сделать отладку более удобной.

В BaseX только эти переменные будут оптимизированы (и, следовательно, возможно предварительно оценены), если на них есть ссылки в исполняемом коде. Например, в следующем выражении $v не будет оцениваться:

declare variable $expensive := (1 to 100000000)[. = 1];
123

Предварительная оценка доступных переменных была выбрана, потому что она позволяет много последующих оптимизаций в BaseX. Тем не менее, ленивая оценка переменных может быть осуществлена ​​путем добавления Q{http://basex.org}lazy аннотация:

declare namespace basex = 'http://basex.org';
declare %basex:lazy variable $expensive := (1 to 100000000)[. = 1];
(1, $expensive)[1]
Другие вопросы по тегам