Функция forEach намного быстрее, чем эквивалент для цикла

0

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

Если вы заметили ошибку, отлично! Но почему цикл foreach был бы намного быстрее. Они идут сразу после друг друга, и если я переключаю порядок вокруг, это не имеет значения.

Сначала быстрее. Это составляет около 5 мс с использованием функции performance.now().

var start = performance.now();
start = performance.now();
$scope.config.formTables.forEach(function (e, i, a) {
    ['tbody', 'thead', 'tfoot'].forEach(function (f, j) {
        if (!$scope.config[e][f]) return;
        $scope.config[e][f].forEach(function (g, k) {
            if(isFunction(g.calculated || {})) g.calculated.apply(g);
        })
    })
});
console.log(performance.now() - start);  

И теперь более медленный, который, как я думал, должен был быть быстрее. Это занимает 100-200 мс.

start = performance.now();
var i,j,k,e,f,g;
for(i = 0; i < $scope.config.formTables.length; i++){
    e = $scope.config[$scope.config.formTables[i]];
    if(e.thead)
    for(j = 0; j < e.thead.length; j++){
        f = e.thead;
        for(k = 0; k < f.length; k++){
            //g = f[j];
            if(isFunction(f[j].calculated || {})) f[j].calculated.apply(f[j]);
        }
    }
    if(e.tfoot)
    for(j = 0; j < e.tfoot.length; j++){
        f = e.tfoot;
        for(k = 0; k < f.length; k++){
            //g = f[j];
            if(isFunction(f[j].calculated || {})) f[j].calculated.apply(f[j]);
        }
    }
    if(e.tbody)
    for(j = 0; j < e.tbody.length; j++){
        f = e.tbody;
        for(k = 0; k < f.length; k++){
            //g = f[j];
            if(isFunction(f[j].calculated || {})) f[j].calculated.apply(f[j]);
        }
    }
}
console.log(performance.now() - start);
Теги:
performance
for-loop
foreach

1 ответ

1
Лучший ответ

Нет, они не эквивалентны из-за этого бит:

for(j = 0; j < e.thead.length; j++){
    f = e.thead;
    for(k = 0; k < f.length; k++){
        //g = f[j];
        if(isFunction(f[j].calculated || {})) f[j].calculated.apply(f[j]);
    }
}

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

Это должно быть просто

if(e.thead) {
    f = e.thead;
    for(k = 0; k < f.length; k++){
        //g = f[j];
        if(isFunction(f[k].calculated || {})) f[k].calculated.apply(f[k]);
    }
}

Обратите внимание, что f == "thead" и этот j никогда не используется в вашей версии forEach.

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

  • 0
    Yikes, ты прав. Это будет иметь большое значение. Он мог бы немного сократить код, избавившись от .apply() и эмулируя forEach() .
  • 0
    @ Squint: Так как я не знал, что именно apply в его случае, я не осмелился коснуться этого. Но это утверждение действительно выглядит подозрительно.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню