Pourquoi itérer dans un tableau vers l’arrière plus vite que vers l’avant

Étant donné ce code:

var arr = []; for (var i = 0; i < 10000; ++i) arr.push(1); 

En avant

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

En arrière

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

Forward codé en dur

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

Pourquoi le retour en arrière est-il beaucoup plus rapide?

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

Parce que votre condition avant doit recevoir la propriété length de votre tableau à chaque fois, alors que l’autre condition ne doit vérifier que «plus grand que 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 

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

Parce que dans la première forme, vous accédez à la length de la propriété du tableau arr pour chaque itération, alors que dans la seconde, vous ne le faites qu’une seule fois.

Si vous voulez les avoir au même rythme, vous pouvez le faire pour une itération avancée;

 for(var i=0, c=arr.length; i 

Ainsi, votre script n'aura pas besoin de prendre la longueur du tableau à tout moment.

Je n’en suis pas tout à fait sûr, mais voici ce que je pense:

Pour le code suivant:

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

Lors de l'exécution, il y a un calcul de longueur après chaque passage de boucle. Cela peut être une opération sortingviale quand elle est seule, mais peut avoir un impact sur 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 travaillons avec ce nombre calculé, plutôt que d'effectuer le calcul de la longueur encore et encore.

Encore une fois, il suffit de mettre mes pensées ici. Observation intéressante en effet!

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.

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

 int len = arr.length; 

vers l’avant

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

en arrière

 for (var i = len; i > 0; --i) { } 

Et ce sont aussi bien:

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

OU

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