如何提高Xquery循环转换的性能

时间:2013-09-13 09:36:51

标签: xquery marklogic

我在我的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占用最大时间。 在这种情况下如何提高性能?请帮忙

4 个答案:

答案 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在树上进行递归,构建新属性及其祖先元素,但复制所有其他节点?