297 votes

Quel est le moyen le plus rapide de parcourir un tableau en JavaScript?

J'apprends d'un autre livre que vous devriez écrire la boucle comme ceci:

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

donc le arr.length ne sera pas calculé à chaque fois.

D'autres disent que le compilateur fera de l'optimisation, il vous suffit d'écrire:

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

Je veux juste savoir quel est le meilleur moyen dans la pratique?

399voto

jondavidjohn Points 28769

Après avoir effectué ce test avec la plupart des navigateurs modernes...

http://jsperf.com/caching-array-length/4

Actuellement, la forme la plus rapide de la boucle (et à mon avis le plus évident du point de vue syntaxique).

un standard pour la boucle avec la durée de mise en cache

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

}

Je dirais que c'est certainement un cas où j'applaudis moteur JavaScript développeurs. Un temps de fonctionnement doit être optimisé pour la clarté, pas de l'intelligence.

106voto

gnur Points 3464

Le moyen le plus rapide de parcourir un tableau JavaScript est:

 var len = arr.length;
while (len--) {
    // blah blah
}
 

Voir http://blogs.oracle.com/greimer/entry/best_way_to_code_a pour une comparaison complète

40voto

Felix Kling Points 247451

Si la commande n'est pas importante, je préfère ce style:

 for(var i = array.length; i--; )
 

Il cache la longueur et est beaucoup plus courte à écrire. Mais il va parcourir le tableau dans l'ordre inverse.

21voto

cocco Points 3958

2014 While est de retour

Pensez juste logique.

Regardez cette

for( var index = 0 , length = array.length ; index < length ; index++ ) {

 //do stuff

}
  1. Besoin de créer au moins 2 variables (index,longueur)
  2. Besoin de vérifier si l'index est plus petite que la longueur
  3. Besoin d'augmentation de l'indice
  4. l' for boucle a 3 paramètres

Maintenant, dites-moi pourquoi cela devrait être plus rapide que:

var length = array.length;

while( --length ) { //or length--

 //do stuff

}
  1. Une variable
  2. Aucune vérification de
  3. l'indice est diminué (Machines préférez)
  4. while n'a qu'un seul paramètre

J'étais totalement confus lorsque google Chrome 28 a montré que la boucle for est plus rapide que le tout. Cela doit avoir ben une sorte de

"Euh, tout le monde est à l'aide de la boucle for, concentrons-nous sur que quand le développement de chrome."

Mais maintenant, en 2014, la boucle while est de retour sur chrome. c'est 2 fois plus rapide , sur d'autres/les navigateurs plus anciens, il était toujours plus rapide.

Dernièrement, j'ai fait quelques tests. Maintenant, dans le monde réel envoirement ces codes ne valent rien et jsperf ne pouvez pas exécuter correctement la boucle while, car il a besoin de recréer le tableau.longueur qui prend également du temps.

vous ne POUVEZ PAS obtenir la vitesse réelle d'une boucle while sur jsperf.

vous avez besoin de créer votre propre fonction et vérifier avec window.performance.now()

Et oui... il n'y a aucun moyen de la boucle while est tout simplement plus rapide.

Le vrai problème est en fait de la manipulation du dom / temps de rendu / le temps de dessin ou ce que vous voulez l'appeler.

Par exemple, j'ai une toile de la scène où j'ai besoin de calculer les coordonnées et les collisions... c'est fait entre 10 à 200 Microsecondes (pas de millisecondes). il prend diverses millisecondes pour rendre tout.De même que dans les DOM.

MAIS

Il y a un autre super-performant de manière à l'aide de la pour les loop dans certains cas... par exemple, pour copier/cloner un tableau

for(
 var i = array.length ;
 i > 0 ;
 arrayCopy[ --i ] = array[ i ] // doing stuff
);

Avis de la configuration des paramètres:

  1. Même que dans la boucle while, je suis à l'aide d'une seule variable
  2. Besoin de vérifier si l'index est plus grand que 0;
  3. Comme vous pouvez le voir, cette approche est différente par rapport à la normale pour la boucle à tout le monde, comme je fais les choses à l'intérieur de la 3ème paramètre et j'ai aussi diminuer directement à l'intérieur de la matrice.

Dit, cela confirme que les machines comme l' --

une écriture que je pensais à faire un peu plus court et de supprimer certains trucs inutiles et écrit en utilisant le même style:

for(
 var i = array.length ;
 i-- ;
 arrayCopy[ i ] = array[ i ] // doing stuff
);

Même si elle est plus courte qu'elle ressemble à l'aide d' i on plus le temps ralentit tout. C'est 1/5 plus lente que la précédente for boucle et de l' while .

Remarque: l' ; est très important après la pour looo sans {}

Même si je viens de vous dire que jsperf n'est pas le meilleur moyen de scripts de test .. j'ai ajouté ces 2 boucles ici

http://jsperf.com/caching-array-length/40

Et voici une autre réponse sur les performances en javascript

http://stackoverflow.com/a/21353032/2450730

Cette réponse est de montrer performant façons d'écrire du code javascript. Donc, si vous ne pouvez pas lire cela, demandez et vous obtiendrez une réponse ou lire un livre sur le javascript http://www.ecma-international.org/ecma-262/5.1/

10voto

przemoc Points 1317

http://jsperf.com/caching-array-length/60

La dernière révision de test, j'ai préparé (par la réutilisation de l'ancienne), montre une chose.

La mise en cache de la longueur n'est pas très important, mais il ne fait pas de mal.

Tout d'abord le test ci-dessus (fraîchement ouvert onglet) donne de meilleurs résultats pour les 4 derniers fragments (3e, 5e, 7e et 10e dans les diagrammes) dans Chrome, Opera et Firefox sur ma Debian Squeeze 64 bits (mon bureau, matériel). Les exécutions ultérieures donner des résultats différents.

En terme de Performance conclusions sont simples:

  • Aller avec une boucle for (marche avant) et test à l'aide de !== au lieu de <.
  • Si vous n'avez pas à réutiliser le tableau plus tard, puis en boucle sur décrémenté de longueur et destructrice shift()-ing tableau est également efficace.

tl;dr

De nos jours (2011.10) ci-dessous modèle semble être le plus rapide possible.

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

L'esprit que la mise en cache arr.length n'est pas ici une importance cruciale, de sorte que vous pouvez tester juste pour i !== arr.length et le rendement ne baissera pas, mais vous aurez une réduction de la taille du code.


PS: je sais que dans l'extrait de code avec shift() de son résultat pourrait être utilisé à la place de l'accès 0e élément, mais j'ai quelque peu oublié qu'après la réutilisation de la révision précédente (qui avait mal lors de la boucle), et plus tard, je ne voulais pas perdre déjà obtenu des résultats.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X