JavaScript performance de la boucle - Pourquoi est-à décrémenter l'itérateur vers 0 plus vite que l'incrémentation

Dans son livre Encore Plus Rapide Des Sites Web Steve Sounders écrit qu'un moyen simple d'améliorer les performances d'une boucle est de décrémenter l'itérateur vers 0 au lieu de l'incrémentation vers la longueur totale (en fait le chapitre a été écrit par Nicholas C. Zakas). Ce changement peut entraîner des économies de jusqu'à 50% de rabais sur l'origine du délai d'exécution, en fonction de la complexité de chaque itération. Par exemple:

var values = [1,2,3,4,5];
var length = values.length;

for (var i=length; i--;) {
   process(values[i]);
}

C'est à peu près identique pour les for boucle, le do-while boucle, et le while boucle.

Je me demandais, quelle est la raison? Pourquoi est-à décrémenter l'itérateur de manière beaucoup plus rapide? (Je suis intéressé par la technique de l'arrière-plan de cette et pas dans les benchmarks de prouver cette affirmation.)


EDIT: À première vue, la boucle de la syntaxe utilisée ici semble incorrect. Il n'y a pas de length-1 ou i>=0, nous allons donc préciser (j'ai été trop confus).

Ici est la boucle de la syntaxe:

for ([initial-expression]; [condition]; [final-expression])
   statement
  • initiale-expression - var i=length

    Cette déclaration de variable est évalué en premier.

  • condition - i--

    Cette expression est évaluée avant chaque itération de boucle. Il va décrémenter la variable avant le premier passage dans la boucle. Si cette expression a pour false la boucle se termine. En JavaScript est 0 == false donc si i enfin est égal à 0 il est interprété comme false et la boucle se termine.

  • final-expression

    Cette expression est évaluée à la fin de chaque itération de boucle (avant la prochaine évaluation de condition). Il n'est pas nécessaire ici, et est vide. Tous les trois expressions sont optionnels dans une boucle for.

La boucle de la syntaxe n'est pas une partie de la question, mais parce que c'est un peu rare, je pense qu'il est intéressant de le préciser. Et peut-être la raison pour laquelle il est plus rapide, car il utilise moins d'expressions (la 0 == false "truc").

n'êtes-vous pas manque une condition de résiliation?
La résiliation condition est i--. Il sera à 0 (false) quand je est 0 avant de le décrémenter. Depuis que l'état a pour effet de bord de la décrémentation de la variable elle-même, il n'est pas nécessaire pour le troisième changement/incrémenter/whatever) expression dans la déclaration.
Pourquoi dois-je commencer à longueur-1? Vous pouvez remplacer les processus d'alerte à vérifier. @Dave - Le terminal de condition renvoie true si le i est égal à 0
En fait, il correspond à false si i est 0. Il évalue à true, le reste du temps.
Le premier passage dans la boucle vérifie la condition-lecture: il évalue i--.

OriginalL'auteur Soundlink | 2010-08-19