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

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

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

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

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

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

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


person ARX    schedule 21.12.2015    source источник


Ответы (2)


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

person Michael Kay    schedule 21.12.2015

В 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]
person Christian Grün    schedule 23.12.2015
comment
Понятия не имел об аннотации lazy. Отличный совет; и спасибо, что поделились. Кроме того, я просто хотел бы перепроверить два ключевых слова, которые вы упомянули: исполняемый код. Если дорогая переменная упоминается в другой переменной в библиотеке, но не в основном модуле, то $expensive не будет предварительно оцениваться, так как она не является частью исполняемого кода. Правильно? - person ARX; 23.12.2015
comment
На самом деле не важно, находится ли переменная в основном или библиотечном модуле. Но это играет роль, если переменная упоминается где-то в коде, который может быть выполнен. Если оно появляется в функции, которая никогда не будет вызываться, оно действительно не будет оцениваться. – Это помогает? - person Christian Grün; 29.12.2015