Оптимизация javascript для цикла

#javascript #jquery #client-side-scripting

#javascript #jquery #сценарии на стороне клиента

Вопрос:

Итак, я уже давно знаю, что

 for ( var i=0, len = myArray.length; i < len; i   ){

}
  

является более эффективным, чем

 for ( var i=0; myArray.length; i   ){

}
  

для больших массивов. Но задавались вопросом, какой прирост производительности действительно дает вам первый?

Сегодня я решил провести несколько тестов. Я создал массив и вставил в него 100 000 чисел.

     var array = []; 
    for( var i = 0; i < 100000; i   ) 
         array.push(i);  
  

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

 console.time('loop'); 

for( var i = 0; i < array.length; i   )
     console.log(i); 

console.timeEnd('loop');  
  

И для второго теста

 console.time('loop'); 

 for( var i = 0, len = array.length; i < len ;i   )
     console.log(i) 

console.timeEnd('loop') 
  

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

Комментарии:

1. Существует довольно полный jspef, выполняемый со всеми видами циклов, while, for, post / pre increment / decrement . Но я не могу найти его на данный момент

2. Но я бы хотел запустить его сам 🙂

3. Вы можете найти jsperf.com полезно в подобных ситуациях. В этом случае я подозреваю, что вызовы console. журнал полностью доминирует над общим временем выполнения.

4. Вот один из них: jsperf.com/loops-7658

5. и еще: jsperf.com/loops-store-length

Ответ №1:

Вот соответствующий jsperf: http://jsperf.com/caching-array-length/4 что показывает, что разница может быть на удивление небольшой.

Ответ №2:

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

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

Ответ №3:

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

Идея о том, что первый пример будет выполняться быстрее, пришла из таких языков, как php, где эквивалентом будет «$ i < sizeof ($array)», поскольку sizeof подсчитывает длину массива на каждой итерации цикла. В отличие от PHP, JavaScript уже знает, какой длины его массивы, поэтому вы в значительной степени просто считываете число напрямую.

В результате получается, что в случае JavaScripts единственная разница между чтением «arrlen» и «somearray.length» заключается в том, куда указывает указатель, поэтому скорость будет практически одинаковой.

Тем не менее, судя по тестам, опубликованным Джозефом, то, как это обрабатывается под капотом, очевидно, не так прямолинейно. В случае chrome 15 inline на самом деле кажется быстрее, в то время как в старых версиях он немного медленнее? o.0