В jQuery более эффективно использовать filter () или просто делать это в each ()? - PullRequest
13 голосов
/ 08 мая 2011

В настоящее время у меня есть код, который извлекает данные через jQuery и затем отображает их с помощью метода each.

Однако у меня возникла проблема с сортировкой, поэтому я посмотрел на использование и добавил, метод jQuery filter перед sort (что имеет смысл).

Сейчас я смотрю на удаление sort, и мне интересно, должен ли я оставить вызов filter как естьили переместите его обратно в each.

Примеры в документации jQuery API для фильтра придерживаются результатов стиля, а не вывода текстового содержимого (в частности, не используя *1015. *)* * each приведет к тому, что нефильтрованные элементы будут повторяться дважды, а не один раз, если проверка была выполнена исключительно в цикле each.

Правильно ли я считаю, что это более эффективно?

РЕДАКТИРОВАТЬ: Dummy exдостаточно.

Так вот:

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

По сравнению с этим:

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

Ответы [ 4 ]

14 голосов
/ 08 мая 2011

Точно так же, как вы сказали:

Документация в настоящее время заявляет что "поставляемый селектор проверено на каждый элемент [...] ", что заставляет меня верить, что делает фильтр и каждый приведет к нефильтрованные элементы в цикле через два раза, по сравнению с только один раз, если проверка была сделана исключительно в каждом цикл.

Из вашего кода мы можем ясно видеть, что вы используете each в обоих случаях, что уже является loop . И filter сам по себе является еще одной петлей , если это для фильтрации). То есть мы сравниваем производительность между двумя циклами и одним циклом . Неизбежно меньше циклов = лучшая производительность .

Я создал эту скрипку и профилировал с помощью Firebug Profiling Tool . Как и ожидалось, второй вариант только с одним циклом будет быстрее . Конечно, при таком небольшом количестве элементов разница составляла всего 0,062 мс. Но очевидно, что разница будет линейно увеличиваться с большим количеством элементов.

Поскольку многие люди очень волнуются, говоря, что разница невелика, и вы должны выбирать в соответствии с ремонтопригодностью, я не стесняюсь выражать свое мнение: я также согласен с этим. На самом деле, я думаю, что более поддерживаемый код без фильтра, но это только вопрос вкуса. Наконец, ваш вопрос был о том, что было более эффективным, и на это ответили, хотя разница невелика.

9 голосов
/ 08 мая 2011

Вы правы, что используете фильтр, и каждый медленнее. Это быстрее использовать только каждый цикл. По возможности оптимизируйте его, чтобы использовать меньше циклов.

Но это микрооптимизация. Это следует оптимизировать только тогда, когда оно «бесплатно» и не требует затрат на читаемый код. Лично я бы выбрал один или другой, основываясь на предпочтениях стиля / читабельности, а не на производительности.

Если у вас нет огромного набора элементов DOM, вы не заметите разницу (а если вы это сделаете, то у вас будут большие проблемы).

И если вы заботитесь об этой разнице, то вам не нужно использовать jQuery, потому что jQuery работает медленно.

Что вам нужно, это удобочитаемость и удобство обслуживания.

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

против

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

Независимо от того, что делает ваш код более читабельным и обслуживаемым, это оптимальный выбор. В качестве отдельного примечания фильтр намного более эффективен, если используется с .map, чем при использовании с .each.

Позвольте мне также отметить, что оптимизация от двух циклов к одному циклу оптимизирует от O(n) до O(n). Это не то, о чем ты должен заботиться. В прошлом я также чувствовал, что «лучше» помещать все в один цикл, потому что вы делаете цикл только один раз, но это действительно ограничивает вас в использовании карты / уменьшения / фильтра.

Напишите значимый, самодокументированный код. Только оптимизируйте узкие места.

3 голосов
/ 08 мая 2011

Я ожидаю, что производительность здесь будет очень схожей, каждый из которых будет немного быстрее (вероятно, это заметно в больших наборах данных, где отфильтрованный набор все еще велик). Фильтр, вероятно, просто зацикливается на множестве (кто-то поправит меня, если я ошибаюсь). Таким образом, первый пример зацикливает полный набор, а затем зацикливает меньший набор. 2-й просто повторяется один раз.

Однако, если возможно, самым быстрым способом было бы включить фильтр в ваш начальный селектор. Допустим, ваша текущая переменная данных является результатом вызова $("div"). Вместо того, чтобы вызывать это и затем фильтровать, используйте это для начала:

$("div[display='true']")
0 голосов
/ 01 марта 2017

Я, как правило, не беспокоюсь о таких микрооптимизациях, поскольку в общей схеме вам, вероятно, придется гораздо больше беспокоиться о производительности, чем jQuery .each() против .filter(), но чтобы ответить на поставленный вопрос, вы должны быть в состоянии получить наилучшие результаты, используя один .filter():

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

Для примитивного сравнения производительности между .each() и .filter() вы можете проверить эту кодовую ручку:

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

Однако, если все, что вы пытаетесь сделать, это выводить все узлы с display="true" на страницу, то вы можете просто сделать, как предложено Джеймсом Монтанем (предполагая, что узел <element>):

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