在jQuery中使用filter()更有效率,还是只在each()中这样做?

时间:2011-05-08 18:28:58

标签: javascript jquery filter each

我目前有代码通过jQuery提取数据,然后使用each方法显示它。

但是,我遇到了排序问题,所以我在filter之前调查了jQuery的sort方法(这是有意义的)。

我现在正在考虑删除sort,并且想知道我是否应该按原样退出filter,或者将其移回each

jQuery API documentation for filter中的示例坚持使用样式结果,而不是文本内容的输出(具体而言,不使用each())。

文档目前声明“[t]他提供的选择器是针对每个元素[...]进行测试的”,这让我相信做filter 一个{{ 1}}会导致非过滤元素循环两次,而只检查一次仅在each循环中进行。

我相信这更有效率吗?

编辑:虚拟的例子。

所以这个:

each

对此:

// data is XML content
data = data.filter(function (a) {
    return ($(this).attr('display') == "true");
});
data.each(function () {
    // do stuff here to output to the page
});

4 个答案:

答案 0 :(得分:14)

正如你所说:

  

文档目前陈述   那个“提供的选择器是   测试了每个元素[...]“,   这让我相信做一个   过滤器和每个将导致   循环的非过滤元素   通过两次,而只有一次   检查是在每个   循环。

通过您的代码,我们可以清楚地看到您在两种情况下使用each,已经是循环filter本身就是另一个循环(如果 它用于过滤,则为)。也就是说,我们将两个循环一个循环之间的性能进行比较。不可避免的更少的循环=更好的性能

我创建了this Fiddle并使用Firebug Profiling Tool进行了分析。正如预期的那样,只有一个循环第二个选项 更快。当然,由于这些少量元素,差异仅为0.062ms。但很明显,差异会随着元素的增加而线性增加。

由于许多人非常担心地说差异很小而你应该根据可维护性进行选择,我随意表达我的意见:我也同意这一点。事实上,我认为更易于维护的代码没有过滤器,但这只是一个品味问题。最后,你的问题是什么更有效,这就是答案,尽管差别很小。

答案 1 :(得分:9)

使用过滤器并且速度较慢是正确的。只使用每个循环更快。在可能的情况下,优化它以使用更少的循环。

但这是微观优化。这应该只在它“免费”时进行优化,而不是以可读代码为代价。我个人会根据风格/可读性偏好选择使用其中一种,而不是基于性能。

除非你有大量的DOM元素,否则你不会注意到它们之间的区别(如果你这样做,你会遇到更大的问题)。

如果你关心这种差异,那么你关心不使用jQuery,因为jQuery很慢。

您应该关注的是可读性和可维护性。

$(selector).filter(function() {
    // get elements I care about
}).each(function() {
    // deal with them
});

VS

$(selector).each(function() {
    // get elements I care about
    if (condition) {
         // deal with them
    }
}

无论哪种方法使您的代码更具可读性和可维护性,都是最佳选择。如果与.map一起使用,则单独的音符过滤器会更强大,如果与.each一起使用。

我还要指出,从两个循环到一个循环的优化是从O(n)O(n)的优化。这不是你应该关心的事情。在过去,我也觉得将所有内容放在一个循环中会“更好”,因为你只循环一次,但这确实限制了你使用map / reduce / filter。

编写有意义的自我记录代码。只是优化瓶颈。

答案 2 :(得分:3)

我希望这里的性能非常相似,每个都稍微快一些(在过滤集仍然很大的大型数据集中可能会很明显)。无论如何,过滤器可能只是在集合上循环(如果我错了,有人会纠正我)。因此,第一个示例循环完整集,然后循环较小的集。第二个只循环一次。

但是,如果可能,最快的方法是在初始选择器中包含过滤器。因此,假设您当前的数据变量是调用$("div")的结果。而不是调用它然后过滤它,使用它开始:

$("div[display='true']")

答案 3 :(得分:0)

我一般不担心像这样的微优化,因为在宏观方案中,你可能比jQuery .each() vs更多地担心性能方面的问题。 。.filter(),但要回答手头的问题,您应该能够使用一个.filter()获得最佳效果:

data.filter(function() {
  return ($(this).attr('display')==="true");
}).appendTo($('body'));

对于.each().filter()之间的原始性能比较,您可以查看此代码集:

http://codepen.io/thdoan/pen/LWpwwa

但是,如果您尝试做的只是将display="true"的所有节点输出到页面,那么您可以按照James Montagne的建议(假设节点为<element>)进行操作:

$('element[display=true]').appendTo($('body'));