web-dev-qa-db-fra.com

Pourquoi l'itération à travers un tableau vers l'arrière est plus rapide que vers l'avant

Compte tenu de ce code:

var arr = [];

for (var i = 0; i < 10000; ++i)
    arr.Push(1);

Avant

for (var i = 0; i < arr.length; ++i) {}

Vers l'arrière

for (var i = arr.length - 1; i >= 0; --i) {}

Renvoi codé en dur

for (var i = 0; i < 10000; ++i) {}

Pourquoi la marche arrière est-elle tellement plus rapide?

Voici le test: http://jsperf.com/array-iteration-direction

50
samccone

Parce que votre condition avant doit recevoir la propriété length de votre tableau à chaque fois, tandis que l'autre condition n'a qu'à vérifier "supérieur à zéro", une tâche très rapide.

Lorsque la longueur de votre tableau ne change pas pendant la boucle et que vous regardez vraiment ns-perfomance, vous pouvez utiliser

for (var i=0, l=arr.length; i<l; i++)

BTW: Au lieu de for (var i = arr.length; i > 0; --i) vous pouvez utiliser for (var i = arr.length; i-- > 0; ) qui traverse vraiment votre tableau de n-1 à 0, pas de n à 1.

81
Bergi

Parce que dans le premier formulaire, vous accédez à la propriété length du tableau arr une fois pour chaque itération, tandis que dans le second, vous ne le faites qu'une seule fois.

8
rabusmar

Si vous voulez les avoir au même rythme, vous pouvez le faire pour l'itération directe;

for(var i=0, c=arr.length; i<c; i++){
}

Ainsi, votre script n'aura pas besoin de prendre la longueur du tableau sur everystep.

6
tcak

Je ne suis pas entièrement sûr de cela, mais voici ma supposition:

Pour le code suivant:

for (var i = 0; i < arr.length; ++i) {;
}

Pendant l'exécution, il y a un calcul de la longueur d'arrivée après chaque passage de boucle. Cela peut être une opération banale lorsqu'elle est autonome, mais peut avoir un impact en ce qui concerne les tableaux multiples/énormes. Pouvez-vous essayer ce qui suit:

 var numItems = arr.length;
    for(var i=0; i< numItems; ++i)
    {
    }

Dans le code ci-dessus, nous calculons la longueur du tableau une seule fois, et nous opérons avec ce nombre calculé, plutôt que d'effectuer le calcul de la longueur encore et encore.

Encore une fois, je viens d'exposer mes pensées ici. Observation intéressante en effet!

4
Gopal Nair

i > 0 est plus rapide que i < arr.length et se produit à chaque itération de la boucle.

Vous pouvez atténuer la différence avec ceci:

for (var i = 0, len = arr.length; i < len; ++i) {;
}

Ce n'est toujours pas aussi rapide que l'élément en arrière, mais plus rapide que votre option en avant.

2
jfriend00

Et ce sont également bons:

var arr= [], L= 10000;
while(L>-1) arr[L]= L--;

OR

var arr= [], i= 0;
while(i<10001) arr[i]=i++;
1
kennebec

faites-le comme ci-dessous, il fonctionnera de la même manière. car arr.length prend du temps à chaque itération vers l'avant.

int len = arr.length;

avant

for (var i = 0; i < len; ++i) {
}

en arrière

for (var i = len; i > 0; --i) {
}
1
dku.rajkumar