简体   繁体   English

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

[英]In jQuery is it more efficient to use filter(), or just do so in the each()?

I currently have code that is pulling in data via jQuery and then displaying it using the each method. 我目前有代码通过jQuery提取数据,然后使用each方法显示它。

However, I was running into an issue with sorting, so I looked into using, and added, jQuery's filter method before the sort (which makes sense). 但是,我遇到了排序问题,所以我在sort之前研究了使用并添加了jQuery的filter方法(这很有意义)。

I'm now looking at removing the sort , and am wondering if I should leave the filter call as-is, or move it back into the each . 我现在正在考虑删除sort ,并且想知道我是否应该按原样保留filter调用,或者将其移回each filter调用。

The examples in the jQuery API documentation for filter stick with styling results, not with the output of textual content (specifically, not using each() ). 过滤器jQuery API文档中的示例包含样式结果,而不是文本内容的输出(特别是不使用each() )。

The documentation currently states that "[t]he supplied selector is tested against each element [...]," which makes me believe that doing a filter and an each would result in non-filtered elements being looped through twice, versus only once if the check was made solely in the each loop. 该文档目前声明“[t]他提供的选择器针对每个元素[...]进行测试”,这使我相信做一个filter each filter会导致非过滤元素循环两次,而不是一次如果检查仅在each循环中进行。

Am I correct in believing that is more efficient? 我是否相信更有效率?

EDIT: Dummy example. 编辑:虚拟的例子。

So this: 所以这:

// 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
});

Versus this: 对此:

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

Exactly as you said: 正如你所说:

The documentation currently states that "the supplied selector is tested against each element [...]" , which makes me believe that doing a filter and an each would result in non-filtered elements being looped through twice, versus only once if the check was made solely in the each loop. 该文档目前声明“提供的选择器针对每个元素[...]进行测试” ,这使我相信做一个过滤器和每个过滤器会导致非过滤元素循环两次,而只检查一次仅在每个循环中完成。

Through your code we can clearly see that you are using each in both cases, what is already a loop . 通过您的代码,我们可以清楚地看到您在两种情况下都使用了each情况,这已经是一个循环 And the filter by itself is another loop (with an if it for filtering). filter本身就是另一个循环如果它用于过滤)。 That is, we are comparing performance between two loops with one loop . 也就是说,我们将两个循环之间的性能与一个循环进行比较。 Inevitably less loops = better performance . 不可避免地更少的循环=更好的性能

I created this Fiddle and profiled with Firebug Profiling Tool . 我创建了这个小提琴,并使用Firebug Profiling Tool进行了分析 As expected, the second option with only one loop is faster . 正如所料, 只有一个循环第二个选项 更快 Of course with this small amount of elements the difference was only 0.062ms. 当然,由于这些少量元素,差异仅为0.062ms。 But obviously the difference would increase linearly with more elements. 但显然,差异将随着更多元素线性增加

Since many people are super worried to say the difference is small and you should choose according to the maintainability, I feel free to express my opinion: I also agree with that. 由于许多人非常担心地说差异很小而你应该根据可维护性进行选择,我随意表达我的意见:我也同意这一点。 In fact I think the more maintainable code is without the filter, but it's only a matter of taste. 事实上,我认为更易于维护的代码没有过滤器,但这只是一个品味问题。 Finally, your question was about what was more efficient and this is what was answered, although the difference is small. 最后,你的问题是什么更有效,这就是答案,虽然差异很小。

You are correct that using filter and each is slower. 你是正确的,使用过滤器,每个都较慢。 It is faster to use just the each loop. 只使用每个循环更快。 Where possible do optimise it to use less loops. 在可能的情况下,优化它以使用更少的循环。

But this is a micro optimisation. 但这是微观优化。 This should only be optimised when it's "free" and doesn't come at a cost of readable code. 这应该只在它“免费”时进行优化,而不是以可读代码为代价。 I would personally pick to use one or the other based on a style / readability preference rather then on performance. 我个人会选择使用一种或另一种基于样式/可读性偏好而不是性能。

Unless you've got a huge sets of DOM elements you won't notice the difference (and if you do then you've got bigger problems). 除非你有大量的DOM元素,否则你不会注意到它们之间的区别(如果你这样做,那么你就会遇到更大的问题)。

And if you care about this difference then you care about not using jQuery because jQuery is slow. 如果你关心这种差异,那么你关心不使用jQuery,因为jQuery很慢。

What you should care about is readability and maintainability. 您应该关注的是可读性和可维护性。

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

vs VS

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

Whichever makes your code more readable and maintainable is the optimum choice. 无论哪个使您的代码更易读和可维护是最佳选择。 As a separate note filter is a lot more powerful if used with .map then if used with .each . 如果与.map一起使用,单独的音符过滤器会更强大,如果与.each一起.each

Let me also point out that optimising from two loops to one loop is optimising from O(n) to O(n) . 我还要指出,从两个循环到一个循环的优化是从O(n)O(n) That's not something you should care about. 这不是你应该关心的事情。 In the past I also feel that it's "better" to put everything in one loop because you only loop once, but this really limits you in using map/reduce/filter. 在过去,我也觉得将所有内容放在一个循环中会“更好”,因为你只循环一次,但这确实限制了你使用map / reduce / filter。

Write meaningful, self-documenting code. 编写有意义的自我记录代码。 Only optimise bottlenecks. 只是优化瓶颈。

I would expect the performance here to be very similar, with the each being slightly faster (probably noticeable in large datasets where the filtered set is still large). 我希望这里的性能非常相似,每个都稍微快一些(在过滤集仍然很大的大型数据集中可能会很明显)。 Filter probably just loops over the set anyway (someone correct me if I'm wrong). 无论如何,过滤器可能只是在集合上循环(如果我错了,有人会纠正我)。 So the first example loops the full set and then loops the smaller set. 因此,第一个示例循环完整集,然后循环较小的集。 The 2nd just loops once. 第二个只循环一次。

However, if possible, the fastest way would be to include the filter in your initial selector. 但是,如果可能,最快的方法是在初始选择器中包含过滤器。 So lets say your current data variable is the result of calling $("div") . 因此,假设您当前的数据变量是调用$("div") Instead of calling that and then filtering it, use this to begin with: 而不是调用它然后过滤它,使用它开始:

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

I generally don't worry about micro-optimizations like this since in the grand scheme of things, you'll likely have a lot more to worry about in terms of performance than jQuery .each() vs. .filter() , but to answer the question at hand, you should be able to get the best results using one .filter() : 我一般不担心像这样的微优化,因为在宏观方案中,你可能比jQuery .each().filter()在性能方面要担心更多,但是回答手头的问题,你应该能够使用一个.filter()获得最好的结果:

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

For a primitive performance comparison between .each() and .filter() , you can check out this codepen: 对于.each().filter()之间的原始性能比较,您可以查看此codepen:

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

However, if all you're trying to do is output all nodes with display="true" to the page, then you can simply do as suggested by James Montagne (assuming the node is <element> ): 但是,如果您要做的只是将所有节点输出display="true"到页面,那么您可以按照James Montagne的建议(假设节点是<element> )执行操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM