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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5929389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 18:49:41  来源:igfitidea点击:

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

javascriptjqueryfiltereach

提问by James Skemp

I currently have code that is pulling in data via jQuery and then displaying it using the eachmethod.

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

However, I was running into an issue with sorting, so I looked into using, and added, jQuery's filtermethod before the sort(which makes sense).

但是,我遇到了排序问题,所以我研究了filtersort(这是有道理的)之前使用并添加了 jQuery 的方法。

I'm now looking at removing the sort, and am wondering if I should leave the filtercall as-is, or move it back into the each.

现在我看取出sort,并想知道如果我要离开filter呼叫原样,或将其移动回each

The examples in the jQuery API documentation for filterstick 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 filterandan eachwould result in non-filtered elements being looped through twice, versus only once if the check was made solely in the eachloop.

文档目前指出“[t] 他提供的选择器针对每个元素进行了测试 [...]”,这让我相信执行 afilteraneach会导致未过滤的元素被循环两次,而如果检查仅在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
    }
});

回答by Erick Petrucelli

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 eachin both cases, what is already a loop. And the filterby itself is another loop(with an ifit for filtering). That is, we are comparing performance between two loopswith one loop. Inevitably less loops = better performance.

通过您的代码,我们可以清楚地看到您each在两种情况下都使用了循环。并且filter它本身是另一个循环(带有用于过滤的if)。也就是说,我们正在用一个循环比较两个循环之间的性能。不可避免地更少的循环 = 更好的性能

I created this Fiddleand profiled with Firebug Profiling Tool. As expected, the second optionwith only one loopis faster. Of course with this small amount of elements the difference was only 0.062ms. But obviously the difference would increase linearlywith more elements.

我创建了这个 Fiddle并使用Firebug Profiling Tool进行了分析。正如所料,第二个选项只有一个循环更快的。当然,对于如此少量的元素,差异仅为 0.062 毫秒。但显然,随着元素的增加,差异会线性增加

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.

既然很多人都超级担心说差别很小,要根据可维护性来选择,我随意发表一下我的看法:我也同意。事实上,我认为更易于维护的代码是没有过滤器,但这只是品味问题。最后,您的问题是关于什么更有效,这就是答案,尽管差异很小。

回答by Raynos

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.

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

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

对比

$(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 .mapthen if used with .each.

无论哪种使您的代码更具可读性和可维护性,都是最佳选择。作为一个单独的音符过滤器,如果使用 with .mapthen if used with ,它会更强大.each

Let me also point out that optimising from two loops to one loop is optimising from O(n)to 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.

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

Write meaningful, self-documenting code. Only optimise bottlenecks.

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

回答by James Montagne

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"). Instead of calling that and then filtering it, use this to begin with:

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

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

回答by thdoan

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()vs. 相比.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(),您可以查看此代码笔:

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'));