J'ai trouvé l'annotation de boucle suivante dans un grand projet sur lequel je travaille (pseudocode):
var someOtherArray = [];
for (var i = 0, n = array.length; i < n; i++) {
someOtherArray[i] = modifyObjetFromArray(array[i]);
}
Ce qui a attiré mon attention, c'est cette variable "n" supplémentaire. Je n'ai jamais vu un for lop écrit de cette façon auparavant.
Évidemment, dans ce scénario, il n'y a aucune raison pour que ce code ne puisse pas être écrit de la manière suivante (ce à quoi je suis très habitué):
var someOtherArray = [];
for (var i = 0; i < array.length; i++) {
someOtherArray[i] = modifyObjetFromArray(array[i]);
}
Mais il m'a fait réfléchir.
Existe-t-il un scénario où l'écriture d'une telle boucle serait logique? L'idée vient à l'esprit que la longueur du "tableau" peut changer pendant l'exécution de la boucle for, mais nous ne voulons pas boucler plus loin que la taille d'origine, mais je ne peux pas imaginer un tel scénario.
Réduire le tableau à l'intérieur de la boucle n'a pas beaucoup de sens non plus, car nous sommes susceptibles d'obtenir OutOfBoundsException.
Existe-t-il un modèle de conception connu où cette annotation est utile?
Modifier Comme indiqué par @ Jerry101, la raison en est la performance. Voici un lien vers le test de performance que j'ai créé: http://jsperf.com/ninforloop . À mon avis, la différence n'est pas assez grande à moins que vous ne répétiez à travers un très large éventail. Le code à partir duquel je l'ai copié ne comportait que jusqu'à 20 éléments, donc je pense que la lisibilité dans ce cas l'emporte sur la considération des performances.
la source
n
peut être plus lente que la variante usingarray.Length
car le JITter peut ne pas remarquer qu'il pourrait éliminer les vérifications des limites du tableau.Réponses:
La variable
n
garantit que le code généré ne récupère pas la longueur du tableau pour chaque itération.Il s'agit d'une optimisation qui peut faire une différence dans l'exécution en fonction de la langue utilisée, que le tableau soit en fait un objet de collection ou un «tableau» JavaScript, et d'autres détails d'optimisation.
la source
n
à la boucle, ce qui est généralement une bonne chose. Je le définirais avant la boucle uniquement si je voulais le réutiliser plus tard.La récupération de la longueur du tableau peut facilement être «plus coûteuse» que l'action réelle sur laquelle vous effectuez une itération.
Donc, si l'ensemble ne change pas, interrogez la longueur une seule fois.
Pas avec des tableaux, mais avec des jeux d'enregistrements provenant d'un serveur SQL, j'ai vu des améliorations spectaculaires en ne demandant pas le nombre d'enregistrements à chaque itération. (bien sûr, ne le faites que si vous pouvez garantir que votre tableau ou jeu d'enregistrements ne sera pas modifié pendant ce processus).
la source
Les personnes qui parlent de performances ont probablement raison, c'est pourquoi cela a été écrit de cette façon (la personne qui l'a écrit de cette façon peut ne pas être correcte car cela affecte de manière significative les performances, mais c'est une autre question).
Cependant, pour répondre à cette partie de votre question, je pense que cela se produira probablement lorsque le but principal de la boucle est de modifier le tableau sur lequel elle boucle. Considérez quelque chose comme ça, en pseudo-code:
Bien sûr, il existe d'autres façons de l'écrire. Dans ce cas, j'aurais pu vérifier les plus en même temps que vérifier si les destinataires acceptaient leurs invitations et produire la liste complète des invités une invitation à la fois. Je ne veux pas nécessairement combiner ces deux opérations, mais je ne peux pas immédiatement penser à une raison pour laquelle c'est définitivement faux et donc cette conception est requise . C'est une option à considérer, à l'occasion.
En fait, je pense que ce qui ne va pas avec ce code, c'est que l'appartenance au
guests
tableau signifie différentes choses à différents points du code. Par conséquent, je ne l'appellerais certainement pas un "modèle", mais je ne sais pas que c'est assez d'un défaut pour exclure de faire quoi que ce soit de ce genre :-)la source
Si possible, vous devez utiliser un itérateur qui traverse tous les éléments du tableau. Vous utilisez le tableau uniquement comme une séquence, pas comme un stockage à accès aléatoire, il serait donc évident qu'un itérateur qui effectue simplement un accès séquentiel serait plus rapide. Imaginez ce que vous pensez qu'un tableau est en fait un arbre binaire, mais quelqu'un a écrit du code qui détermine la "longueur" en comptant les éléments, et du code qui accède au i-ème élément, également en parcourant l'élément, chacun en O (n ). Un itérateur peut être très rapide, votre boucle sera ralentie.
la source