Говоря об оптимизации JavaScript можно увидеть множество примеров того, как следует делать или не делать. Мнения некоторых авторов звучат убедительно, их примеры внушают уверенность. И главным образом, подобных рекомендаций в сети много, но значительно меньше статистики по ним. Вот и сегодня на страницах GitHub'а в поле зрения был пойман ранее знакомый теоретический материал по оптимизации циклов for.
Вот так выглядит исходный код рецептов:
<!doctype html>
<html lang="en">
<head>
<title>JavaScript optimized for loops</title>
<meta charset="utf-8">
</head>
<body>
<script>
/* Title: for loops
* Description: optimized for loops
*/
// sub-optimal loop
for (var i = 0; i < myarray.length; i++) {
// do something with myarray[i]
}
// optimization 1 - cache the length of the array with the use of `max`
for (var i = 0, max = myarray.length; i < max; i++) {
// do something with myarray[i]
}
// optimization 2 - use single var pattern for consistency
// NOTE: A drawback is that it makes it a little harder to copy and paste whole loops while refactoring code.
var i = 0,
max,
myarray = [];
for (i = 0, max = myarray.length; i < max; i++) {
// do something with myarray[i]
}
// optimization 3 - substitute `i++` with `i = i + 1` or `i += 1` to avoid excessive trickiness
var i = 0,
max,
myarray = [];
for (i = 0, max = myarray.length; i < max; i += 1) {
// do something with myarray[i]
}
// preferred 1
var i, myarray = [];
for (i = myarray.length; i--;) {
// do something with myarray[i]
}
// preferred 2
var myarray = [],
i = myarray.length;
while (i--) {
// do something with myarray[i]
}
</script>
</body>
</html>
Вот так он был переработан мной для опытов:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JavaScript Patterns</title>
<meta charset="utf-8">
</head>
<body>
<script>
console.time('method 1');
var myarray1 = new Array(999999);
for (var i = 0; i < myarray1.length; i++) {
myarray1[i] = {'habra': 'habr'};
}
console.timeEnd('method 1');
console.time('method 2');
var myarray2 = new Array(999999);
for (var i = 0, max = myarray2.length; i < max; i++) {
myarray2[i] = {'habra': 'habr'};
}
console.timeEnd('method 2');
console.time('method 3');
var i = 0,
max,
myarray3 = new Array(999999);
for (i = 0, max = myarray3.length; i < max; i++) {
myarray3[i] = {'habra': 'habr'};
}
console.timeEnd('method 3');
console.time('method 4');
var i = 0,
max,
myarray4 = new Array(999999);
for (i = 0, max = myarray4.length; i < max; i += 1) {
myarray4[i] = {'habra': 'habr'};
}
console.timeEnd('method 4');
console.time('method 5');
var i, myarray5 = new Array(999999);
for (i = myarray5.length; i--;) {
myarray5[i] = {'habra': 'habr'};
}
console.timeEnd('method 5');
console.time('method 6');
var myarray6 = new Array(999999),
i = myarray6.length;
while (i--) {
myarray6[i] = {'habra': 'habr'};
}
console.timeEnd('method 6');
</script>
</body>
</html>
Результат
Опыт проводился в трёх браузерах под Linux: Firefox 15.0.1, Chromium 18.0 и Chrome 22.0.
Во время опыта менялись подходы: применялась инструкция delete к удалении объектов; был использован массив с одним именем; очищался кэш браузера; даже каждый из шести тестов был изолирован и запускался самостоятельно.
Во всех множественных случаях прогонки тестов результат был один и тот же — непредсказуемый. Вопреки тому, что предполагалась закономерность которая должна была подтвердить предпочтение использовать методы 5 и 6.
Так давайте разберемся, оптимизация циклов for в JavaScript — это миф или реальность?
Автор: vodka_ru