Maison interface Web js tutoriel Exploration approfondie des problèmes d'efficacité et d'optimisation associée des boucles for dans les compétences JavaScript_javascript

Exploration approfondie des problèmes d'efficacité et d'optimisation associée des boucles for dans les compétences JavaScript_javascript

May 16, 2016 pm 03:10 PM
for javascript js 循环

Bibliothèque Underscore.js

Combien de boucles avez-vous écrites en une journée (semaine) ?

var i;
for(i = 0; i < someArray.length; i++) {
 var someThing = someArray[i];
 doSomeWorkOn(someThing);
}

Copier après la connexion

C'est inoffensif, bien sûr, mais c'est moche et bizarre et il n'y a pas vraiment de quoi se plaindre. Mais cette façon d’écrire est trop banale.

var i,
 j;
for(i = 0; i < someArray.length; i++) {
 var someThing = someArray[i];
 for(j = 0; j < someThing.stuff.length; j++) {
   doSomeWorkOn(someThing.stuff[j]);
 }
}

Copier après la connexion

Vous étendez du mauvais code, et avant de lancer un tas de si, vous êtes déjà fou.
Je n'ai pas écrit de boucle depuis deux ans.
"De quoi tu parles ?"
C'est vrai, une mauvaise blague. En fait, pas aucun (ok, j’en ai écrit quelques-uns), car je n’écris pas de boucles et mon code est plus facile à comprendre.
Comment?

_.each(someArray, function(someThing) {
 doSomeWorkOn(someThing);
})

Copier après la connexion

Ou mieux encore :

_.each(someArray, doSomeWorkOn);

Copier après la connexion

C'est ce que fait underscorejs. Propre, simple, lisible, court, pas de variables intermédiaires, pas de tonnes de points-virgules, simple et très élégant.
Voici quelques exemples supplémentaires.

var i,
 result = [];
for(i = 0; i < someArray.length; i++) {
 var someThing = someArray[i];
 // 打到这,我已经手疼了
 if(someThing.isAwesome === true) {
   result.push(someArray[i]);
 }
}

Copier après la connexion

Encore une fois, un cas d'utilisation typique pour perdre du temps à utiliser des boucles. Même si ces sites font la promotion de la lutte contre le tabac et du végétarisme, je me sens indigné lorsque je vois ces codes. Regardez la manière simple de l’écrire.

var result = _.filter(someArray, function(someThing) {
 return someThing.isAwesome === true;
})

Copier après la connexion

Comme le nom du filtre en trait de soulignement, seulement 3 lignes de code peuvent vous donner un nouveau tableau.
Ou souhaitez-vous convertir ces tableaux sous une autre forme ?

var result = _.map(someArray, function(someThing) {
 return trasformTheThing(someThing);
})

Copier après la connexion

Les trois exemples ci-dessus sont suffisants dans la vie quotidienne, mais ces fonctions ne suffisent pas pour que le soulignement soit mis sur la table.

var grandTotal = 0,
 somePercentage = 1.07,
 severalNumbers = [33, 54, 42],
 i; // don't forget to hoist those indices;
for(i = 0; i < severalNumbers.length; i++) {
 var aNumber = severalNumbers[i];
 grandTotal += aNumber * somePercentage;
}

Copier après la connexion

version soulignée

var somePercentage = 1.07,
 severalNumbers = [33, 54, 42],
 grandTotal;
grandTotal = _.reduce(severalNumbers, function(runningTotal, aNumber) {
 return runningTotal + (aNumber * somePercentage);
}, 0)

Copier après la connexion

Cela peut sembler un peu étrange au début. J'ai vérifié la documentation sur la réduction et découvert son existence. Puisque je refuse d'utiliser des boucles, c'est mon premier choix. Les éléments ci-dessus ne sont qu'une introduction. La bibliothèque underscorejs possède également de nombreuses fonctions impressionnantes.

Défi de cycle sans utilisation de 30 jours.

N'utilisez aucune boucle pendant les 30 prochains jours. Si vous voyez un tas de choses désagréables et grossières, remplacez-les par chacune ou par une carte. Utilisez un peu plus de réduction.

Vous devez noter que Underscore est la passerelle vers la programmation fonctionnelle. Une manière visible et invisible. Une bonne voie à suivre.


Note OurJS* Les navigateurs modernes prennent actuellement en charge chacune des méthodes de filtrage, de mappage et de réduction, mais la bibliothèque de traits de soulignement peut atteindre la compatibilité avec les anciennes versions d'IE. Voici un exemple écrit à l'aide des méthodes natives ES5 :

.
[3,4,5,3,3].forEach(function(obj){
  console.log(obj);
});

[1,2,3,4,5].filter(function(obj){
  return obj < 3
});

[9,8,5,2,3,4,5].map(function(obj){
  return obj + 2;
});

[1,2,3,4,5].reduce(function(pre, cur, idx, arr) {
  console.log(idx);  //4 个循环: 2-5
  return pre + cur;
});  //15

//sort方法同样很有用
[9,8,5,2,3,4,5].sort(function(obj1, obj2){
  return obj1 - obj2;
});

Copier après la connexion

for in et for boucle

Quelqu'un a souligné que l'efficacité de for in est bien inférieure à celle de for loop. Testons maintenant l'efficacité de l'utilisation de for in, for loop et forEach dans différents navigateurs lors du traitement de grands tableaux.

À l'heure actuelle, la plupart des logiciels open source mettront en cache la longueur du tableau dans la boucle for, car l'opinion courante est que certains navigateurs Array.length recalculeront la longueur du tableau à chaque fois, donc des variables temporaires sont généralement utilisées pour stocker la longueur du tableau. à l'avance, comme :

for (var idx = 0, len = testArray.length; idx < len; idx++) {
 //do sth.
}
Copier après la connexion
Copier après la connexion

Nous testerons également la différence de performances entre la mise en cache et l'absence de mise en cache.

Ajoutez également une opération de sommation dans chaque boucle de test pour montrer qu'il ne s'agit pas d'une boucle vide.

for (var idx = 0, len = testArray.length; idx < len; idx++) {
 //do sth.
}
Copier après la connexion
Copier après la connexion

Nous testerons également la différence de performances entre la mise en cache et l'absence de mise en cache.

Ajoutez également une opération de sommation dans chaque boucle de test pour montrer qu'il ne s'agit pas d'une boucle vide.

Le code de test est le suivant, cliquez sur Exécuter pour voir
Code HTML

<h4 id="browser"></h4>
<table id="results" class="table"></table>
Copier après la connexion

Code JavaScript

function () {

 //准备测试数据, 有200万条数据的大数组
 var testArray = []
  , testObject = {}
  , idx
  , len = 2000000
  , tmp = 0
  , $results = $("#results")
  , $browser = $("#browser")
  ;

 $browser.html(navigator.userAgent);
 $results.html('');

 for (var i = 0; i < len; i++) {
  var number = Math.random(); //若希望加快运算速度可使用取整:Math.random() * 10 | 0
  testArray.push(number);
  testObject[i] = number;
 }

 $results.append('<tr><th>测试代码</th><th>计算结果</th><th>所需时间,毫秒</th></tr>');

 //测试函数
 var test = function(testFunc) {
  var startTime
   , endTime
   , result
   ;

  startTime = new Date();
  tmp = 0;
  testFunc();
  endTime  = new Date();

  //计算测试用例(Test Case)运行所需要的时间
  result = endTime - startTime;
  $results.append('<tr><td><pre>{0}</pre></td><td>{1}</td><td>{2}</td></tr>'.format(testFunc.toString(), tmp | 0, result));
 };


 test(function() {
  //测试for in 的效率
  for (idx in testArray) {
   tmp += testArray[idx]; //经测试,idx是string类型,可能是慢的原因之一
  }
 });

 test(function() {
  //测试for loop循环的效率
  for (idx = 0, len = testArray.length; idx < len; idx++) {
   tmp += testArray[idx];
  }
 });

 test(function() {
  //测试forEach的效率
  testArray.forEach(function(data) {
   tmp += data;
  });
 });

 test(function() {
  //测试不缓存Array.length时效率
  for (idx = 0; idx < testArray.length; idx++) {
   tmp += testArray[idx];
  }
 });

 test(function() {
  //测试使用{} (Object) 存健值对时,使用for in的效率如何
  for (idx in testObject) {
   tmp += testObject[idx];
  }
 });
 
 test(function() {
  //测试从{} Object查值时的效率如何(这里的健key值事先己知)
  for (idx = 0, len = testArray.length; idx < len; idx++) {
   tmp += testObject[idx];
  }
 });

}

Copier après la connexion

Exécuter [Veuillez patienter un instant]
Résultats des tests
Les résultats des tests peuvent varier en fonction du calcul. Ceci est un résumé des résultats des tests de Firefox, Chrome et IE exécutés sur ma machine.

2016313110044207.jpg (971×678)

Voici plusieurs conclusions observées

  • For in est beaucoup plus lent que la boucle for, au moins 20 fois plus lente dans Chrome
  • FF a optimisé forEach (ES5), et ses performances sont meilleures que celles de la boucle for, mais les performances de Chrome/IEn sont médiocres
  • La mise en cache FF/Chrome d'Array.length est un peu plus lente que son utilisation directe. À l'exception de la dernière version d'IE, l'amélioration des performances est minime (c'est très inattendu)
  • Dans certains cas, les performances du moteur JS du FF semblent meilleures que celles du V8
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Article chaud

Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Article chaud

Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

17 façons de résoudre l'écran bleu kernel_security_check_failure 17 façons de résoudre l'écran bleu kernel_security_check_failure Feb 12, 2024 pm 08:51 PM

17 façons de résoudre l'écran bleu kernel_security_check_failure

Recommandé : Excellent projet de détection et de reconnaissance des visages open source JS Recommandé : Excellent projet de détection et de reconnaissance des visages open source JS Apr 03, 2024 am 11:55 AM

Recommandé : Excellent projet de détection et de reconnaissance des visages open source JS

Conseils de développement PHP et JS : maîtrisez la méthode de création de graphiques en bougies boursières Conseils de développement PHP et JS : maîtrisez la méthode de création de graphiques en bougies boursières Dec 18, 2023 pm 03:39 PM

Conseils de développement PHP et JS : maîtrisez la méthode de création de graphiques en bougies boursières

Comment désinstaller Skype Entreprise sur Win10 ? Comment désinstaller complètement Skype sur votre ordinateur Comment désinstaller Skype Entreprise sur Win10 ? Comment désinstaller complètement Skype sur votre ordinateur Feb 13, 2024 pm 12:30 PM

Comment désinstaller Skype Entreprise sur Win10 ? Comment désinstaller complètement Skype sur votre ordinateur

Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP Jan 05, 2024 pm 06:08 PM

Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP

La relation entre js et vue La relation entre js et vue Mar 11, 2024 pm 05:21 PM

La relation entre js et vue

Quelles sont les alternatives aux appels récursifs dans les fonctions Java ? Quelles sont les alternatives aux appels récursifs dans les fonctions Java ? May 05, 2024 am 10:42 AM

Quelles sont les alternatives aux appels récursifs dans les fonctions Java ?

L'expression lambda sort de la boucle L'expression lambda sort de la boucle Feb 20, 2024 am 08:47 AM

L'expression lambda sort de la boucle

See all articles