我目前有代码通过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
});
答案 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'));