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]