Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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).

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.

The examples in the jQuery API documentation for filter stick with styling results, not with the output of textual content (specifically, not using 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.

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
    }
});
like image 518
James Skemp Avatar asked May 08 '11 18:05

James Skemp


3 Answers

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. And the filter by itself is another loop (with an if it for filtering). 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. 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. 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.

like image 52
Erick Petrucelli Avatar answered Oct 04 '22 03:10

Erick Petrucelli


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).

And if you care about this difference then you care about not using jQuery because jQuery is slow.

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 .map then 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.

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

like image 43
Raynos Avatar answered Oct 04 '22 04:10

Raynos


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[display='true']")
like image 30
James Montagne Avatar answered Oct 04 '22 03:10

James Montagne