$.каждый() vs for () цикл-и производительность



это в основном просто некоторые вещи, которые мне было интересно, может быть, кто-то может дать мне немного больше информации о них, я поделюсь тем, что я заметил до сих пор!



Первое, что мне было интересно... есть ли какая-либо разница хорошая или причина для использования:



$('element').each(function (i, el) { });



-- против --



$.each($('element'), function (i, el) { });



глядя на документы jQuery, я не вижу никакой рифмы или причины для одного или другого (возможно, вы знаете экземпляр или дополнительные вещи одно может сделать над другим.



но что еще более важно меня беспокоит скорость здесь



// As opposed to $.each() looping through a jQuery object
// -- 8x faster
for (var i = 0, $('.whatever').length; i < len; i++) {
$('.whatever')[i] // do stuff
}


если вы проверите это jsFiddle демо здесь, вы увидите, что разница в скорости в основном эквивалентна с любым из них, но что еще более важно, я чувствую, что должен всегда использовать for() петли...



Я просто модульное тестирование (цикл через каждый из 5 различных сценариев функции, 50 000 раз), просто перебирая кучу элементов списка и устанавливая data-newAttr, ничего особенного.





вопрос:: я думаю, мой самый большой вопрос, почему бы и нет всегда использовать для циклов при итерации через объект?? Есть ли вообще смысл использовать $.каждый()? Вы всегда используете for () loops даже при прохождении объектов jQuery?



jsFiddle демо здесь



Function type:                  Execution Time:
_testArea.each() + $(this) 1947 <-- using $(this) slows it down tremendously
$.each() + $(this) 1940
_testArea.each() + el(plain JS) 458 <-- using the Element speeds things up
$.each() + el(plain JS) 452
for() loop + plainJS[0] iteration 236 <-- over 8x faster


только мои 2 цента. :)

367   6  

6 ответов:

одно .each() позволяет сделать это не может быть сделано с for цикл сцепление.

$('.rows').each(function(i, el) {
    // do something with ALL the rows
}).filter('.even').each(function(i, el) {
    // do something with the even rows
});

Я играл с вашим JSFiddle чтобы увидеть, как цепочка будет влиять на производительность в тех случаях, когда вам нужно перебирать подмножества исходного набора согласованных элементов.

результат не был таким уж неожиданным, хотя я думаю, что накладные расходы end() здесь было преувеличено из-за сочетания нескольких элементов и множества петель. Кроме этого: простые петли JS все еще немного быстрее, но весит ли это до добавленной читаемости .each() (и цепочка) является спорным.

одна вещь, которую вы получаете с .each() является автоматической локальной областью (потому что вы вызываете анонимную функцию для каждого объекта), что в свою очередь означает, что если вы создаете еще больше анонимных функций/замыканий/обработчиков событий/что угодно на каждой итерации, вам никогда не придется беспокоиться о том, что ваши обработчики используют переменную. То есть JavaScript не действует как другие языки, когда речь заходит о локальных областях, но поскольку вы можете объявить переменную в любом месте, она может обмануть вас иногда.

другими словами, это неправильно:

var idx,el;
for (idx = 0; idx <someObjectArray.length; idx++){
   el = someObjectArray[idx]
   el.someEventHandler(function(){  
       alert( "this is element " + idx);
   }); 
}

всякий раз, когда какой-либо из этих объектов вызывает их "someEvent" после этого цикла (обратите внимание, что это составлено), предупреждение всегда будет говорить все, что было в последний раз назначено idx, который должен быть (на момент вызова) someObjectArray.length;

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

var idx,el;
for (idx = 0; idx <someObjectArray.length; idx++){
   el = someObjectArray[idx];
   (function(){
       var localidx = idx;
       el.someEventHandler(function(){  
           alert( "this is element " + localidx);
       }); 
   })();
}

как вы видите, это ужасно, но должно сработать. Каждый обработчик событий получает свою собственную копию localidx

теперь сравните это с .each()

$(someObjectArray).each(function (idx, el) { 
   el.someEventHandler(function(){  
       alert( "this is element " + idx);
   }); 
});

много проще, не так ли?

jQuery.против каждого цикла

преимущества jQuery.каждый:

  • хорошо вписывается в код jQuery (подключение и стиль).
  • не беспокойтесь о области (ссылки на итератор и объект будут постоянными).
  • может использоваться повсеместно (для всех видов объектов и итерации по ключам объектов).

преимущества цикла:

  • высокая производительность (для игр/анимации/большие набор данных.)
  • полный контроль над итератором (пропустить элементы, элементы соединения из списка и т. д.).
  • for-loop всегда будет работать, так как нет никакой зависимости от jQuery.
  • тот же знакомый синтаксис, что и большинство других подобных языков.

пример кода

это пример кода, как я предпочитаю перебирать список.

var list = ['a', 'b', 'c', 'd', 'e', 'f'];

jQuery.каждый:

$.each(list, function(i, v)
{
    // code...
});

For-loop без закрытие:

for(var i=0,v,n=list.length;i<n;i+=1)
{
    v = list[i];
    // code...
}

For-loop с закрытием:

for(var i=0,n=list.length;i<n;i+=1)
{
    (function(i, v)
    {
        // code...
    })(i, list[i]);
}

примечание: Я предлагаю вам просто использовать стандартный for-loop, и использовать только закрытие, когда это необходимо. Однако, когда ваш код выглядит больше как jQuery, чем Javascript в любом случае, было бы проще просто использовать $.each. В случае проблем с производительностью, вы всегда можете посмотреть на него позже.

когда я пошел по вашей ссылке вот два номера, которые я получил:

$.each() + el(plain JS) 401
for() loop + plainJS[0] iteration   377

Если разница так мала, тогда идите с тем, который наиболее читаем, но, если у вас очень высокие требования к времени, вам может просто нужно пойти с тем, что в конечном итоге будет самым быстрым.

Я бы предложил вам написать свою программу, чтобы использовать три разных метода, два выше, а затем использовать foreach, найденный в более новых версиях javascript, и для тех браузеров, которые его не поддерживают, вы можете добавить его в качестве прототипа.

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach

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

для вашего первого вопроса, я бы пошел с $('element').each как это гораздо легче читать, но это только мое мнение.

Я провел несколько простых тестов производительности в то время как назад http://jsperf.com/forloops3. кажется, что придерживаясь простой, старый for loop (где это возможно) путь :)

на самом деле есть большая разница между $.каждый и.)($ каждый.)(

Они делают немного разные вещи в зависимости от того, что вы проходите.

http://api.jquery.com/each/ vs http://api.jquery.com/jquery.each/

jquery.каждый из них является универсальным итератором, где $().каждый () является специфичным для коллекции jquery.

Также см.:http://jsperf.com/each-vs-each-vs-for-in/9

Comments

    Ничего не найдено.