2015-12-21 2 views
2

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

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

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

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

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

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

ответ

2

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

2

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

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

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

declare namespace basex = 'http://basex.org'; 
declare %basex:lazy variable $expensive := (1 to 100000000)[. = 1]; 
(1, $expensive)[1] 
+0

не имел ни малейшего представления о 'lazy' аннотацию. Большой наконечник; и спасибо, что разделили его. Помимо этого, я бы просто хотел дважды проверить два ключевых слова, которые вы упомянули: «выполненный код». Если дорогая переменная ссылается на другую переменную в модуле _library_, но не в _main module_, тогда $ дорогое не будет предварительно оценено, так как оно не является частью исполняемого кода. Правильно? – ARX

+0

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

+0

Он делает! Спасибо. – ARX