我在我的Xquery中使用了一个特定的方法,如下所示
declare function ctrlv($node, $node-id as xs:string)
{
<z:b>
{
(attribute {"xml:id"}{$node/@xml:id})
}</z:b>
};
使用diff $ node将此特定函数循环11,000次。单独给定的方法占整个响应时间的50-60%(大约8秒)。当我执行性能分析时,它显示$ node / @ xml:id占用最大时间。 在这种情况下如何提高性能?请帮忙
答案 0 :(得分:2)
我不太清楚为什么要构造一个与$node
具有相同名称的新属性,并插入@id
的值。因为使用元素的构造应该有一些开销,我猜以下更快(并且应该提供相同的输出):
declare function ctrlv($node, $node-id as xs:string)
{
<z:b>
{$node/@xml:id}
</z:b>
};
此外,$node-id
从未在您的函数中使用,因此您可能希望将其作为参数删除。
答案 1 :(得分:1)
提高这些事物的速度有渐进的步骤。 XML元素的创建有点昂贵(尽管.3毫秒并不是那么糟糕......但是如果你做了10k那些它会加起来)
以下是识别最频繁使用的表达式时的一些步骤。 他们建议您在确定性能问题后该怎么做,而不是之前, 因为大多数情况下性能影响很小,代码可读性和可维护性更重要。但是一旦你确定了一个热点,请考虑以下几点:
限制函数调用 - 这个简单的东西可以在没有函数的情况下内联完成。 限制绑定到变量 循环限制 限制元素和属性的动态构造
当然,你无法完成所有这些,但你可以决定痛苦最大的地方并在那里应用概念。 例如,上面的调用可以改为内联为
<z:b xml:id="{$node/@xml:id}"/>
尝试将此内联放置在您尝试该功能的位置,并查看结果。
另请注意,探查器有时会提供误导性信息。许多表达式都被懒惰地评估,并倾向于将时间归因于它们的使用位置而不是声明它们的位置。
答案 2 :(得分:0)
你的电脑特别慢吗?分析器告诉我这个运行时间为250毫秒。
declare function local:do($node)
{
element b { $node/@xml:id }
};
distinct-values(
(1 to 10 * 1000) ! local:do(<test xml:id="a123"/>))
要尝试的另一件事是XSLT实现。您仍然需要评估$node/@xml:id
11,000次,但要更快地达到该表达式。
答案 3 :(得分:-2)
如果您使用相同的uri将修改后的文档写回数据库,请尝试使用xdmp:node-replace()函数来修改属性值,而不是在内存中构建新的文档树并将其写回到数据库。
如果你不是,循环中会发生什么?您是在每次迭代中构建一个新文档,还是迭代器使用typeswitch在树上进行递归,构建新属性及其祖先元素,但复制所有其他节点?