Vous pouvez obtenir le même résultat avec des boucles for et while :
Tandis que :
$i = 0;
while ($i <= 10){
print $i."\n";
$i++;
};
Pour :
for ($i = 0; $i <= 10; $i++){
print $i."\n";
}
Mais lequel est le plus rapide ?
Vous pouvez obtenir le même résultat avec des boucles for et while :
Tandis que :
$i = 0;
while ($i <= 10){
print $i."\n";
$i++;
};
Pour :
for ($i = 0; $i <= 10; $i++){
print $i."\n";
}
Mais lequel est le plus rapide ?
S'il s'agissait d'un programme en C, je ne dirais rien. Le compilateur produira exactement le même code. Comme ce n'est pas le cas, je dis qu'il faut le mesurer. En réalité, il ne s'agit pas de savoir quelle construction de boucle est la plus rapide, puisque le gain de temps est minuscule. Il s'agit de savoir quelle construction de boucle est plus facile à maintenir. Dans le cas que vous avez montré, une boucle for est plus appropriée parce que c'est ce que les autres programmeurs (y compris les futurs vous, je l'espère) s'attendront à y voir.
J'ai utilisé une boucle for et while sur une machine de test solide (aucun processus tiers non standard en arrière-plan). J'ai exécuté une boucle for loop
vs while loop
en ce qui concerne la modification de la propriété de style de 10 000 <button>
nœuds.
Le test a été exécuté consécutivement 10 fois, 1 fois avec un délai de 1500 millisecondes avant l'exécution :
Voici le javascript très simple que j'ai créé à cette fin
function runPerfTest() {
"use strict";
function perfTest(fn, ns) {
console.time(ns);
fn();
console.timeEnd(ns);
}
var target = document.getElementsByTagName('button');
function whileDisplayNone() {
var x = 0;
while (target.length > x) {
target[x].style.display = 'none';
x++;
}
}
function forLoopDisplayNone() {
for (var i = 0; i < target.length; i++) {
target[i].style.display = 'none';
}
}
function reset() {
for (var i = 0; i < target.length; i++) {
target[i].style.display = 'inline-block';
}
}
perfTest(function() {
whileDisplayNone();
}, 'whileDisplayNone');
reset();
perfTest(function() {
forLoopDisplayNone();
}, 'forLoopDisplayNone');
reset();
};
$(function(){
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
setTimeout(function(){
console.log('cool run');
runPerfTest();
}, 1500);
});
Voici les résultats que j'ai obtenus
pen.js:8 whileDisplayNone: 36.987ms
pen.js:8 forLoopDisplayNone: 20.825ms
pen.js:8 whileDisplayNone: 19.072ms
pen.js:8 forLoopDisplayNone: 25.701ms
pen.js:8 whileDisplayNone: 21.534ms
pen.js:8 forLoopDisplayNone: 22.570ms
pen.js:8 whileDisplayNone: 16.339ms
pen.js:8 forLoopDisplayNone: 21.083ms
pen.js:8 whileDisplayNone: 16.971ms
pen.js:8 forLoopDisplayNone: 16.394ms
pen.js:8 whileDisplayNone: 15.734ms
pen.js:8 forLoopDisplayNone: 21.363ms
pen.js:8 whileDisplayNone: 18.682ms
pen.js:8 forLoopDisplayNone: 18.206ms
pen.js:8 whileDisplayNone: 19.371ms
pen.js:8 forLoopDisplayNone: 17.401ms
pen.js:8 whileDisplayNone: 26.123ms
pen.js:8 forLoopDisplayNone: 19.004ms
pen.js:61 cool run
pen.js:8 whileDisplayNone: 20.315ms
pen.js:8 forLoopDisplayNone: 17.462ms
Voici le lien de démonstration
Mise à jour
Un autre test que j'ai effectué se trouve ci-dessous. Il met en œuvre deux algorithmes factoriels écrits différemment, l'un utilisant une boucle for et l'autre une boucle while.
Voici le code :
function runPerfTest() {
"use strict";
function perfTest(fn, ns) {
console.time(ns);
fn();
console.timeEnd(ns);
}
function whileFactorial(num) {
if (num < 0) {
return -1;
}
else if (num === 0) {
return 1;
}
var factl = num;
while (num-- > 2) {
factl *= num;
}
return factl;
}
function forFactorial(num) {
var factl = 1;
for (var cur = 1; cur <= num; cur++) {
factl *= cur;
}
return factl;
}
perfTest(function(){
console.log('Result (100000):'+forFactorial(80));
}, 'forFactorial100');
perfTest(function(){
console.log('Result (100000):'+whileFactorial(80));
}, 'whileFactorial100');
};
(function(){
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
console.log('cold run @1500ms timeout:');
setTimeout(runPerfTest, 1500);
})();
Et les résultats pour le benchmark factoriel :
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.280ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.241ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.254ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.254ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.285ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.294ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.181ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.172ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.195ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.279ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.185ms
pen.js:55 cold run @1500ms timeout:
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.404ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.314ms
Conclusion : Quelle que soit la taille de l'échantillon ou le type de tâche spécifique testé, il n'y a pas de gagnant clair en termes de performances entre une boucle while et une boucle for. Tests effectués sur un MacAir avec OS X Mavericks sur Chrome evergreen.
Fixer le nombre d'itérations de la boucle à 10 000.
Trouver le temps en millisecondes>Exécuter la boucle>retrouver le temps en millisecondes et soustraire le premier chronomètre.
Faites-le pour les deux codes, celui qui a le moins de millisecondes fonctionne plus rapidement. Vous pouvez exécuter le test plusieurs fois et faire une moyenne pour réduire la probabilité que les processus d'arrière-plan influencent le test.
Vous obtiendrez probablement des temps très similaires sur les deux, mais je suis curieux de voir si l'un d'entre eux est toujours légèrement plus rapide.
Certains compilateurs optimisateurs seront capables de mieux dérouler une boucle avec une boucle for, mais il y a fort à parier que si vous faites quelque chose qui peut être déroulé, un compilateur suffisamment intelligent pour le faire le sera probablement aussi pour interpréter la condition de boucle de votre boucle while comme quelque chose qu'il peut également dérouler.
J'ai également essayé de comparer les différents types de boucles en C#. J'ai utilisé le même code que Shane mais j'ai aussi essayé avec un do-while et j'ai trouvé que c'était le plus rapide. Voici le code :
using System;
using System.Diagnostics;
public class Program
{
public static void Main()
{
int max = 9999999;
Stopwatch stopWatch = new Stopwatch();
Console.WriteLine("Do While Loop: ");
stopWatch.Start();
DoWhileLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("While Loop: ");
stopWatch.Start();
WhileLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("For Loop: ");
stopWatch.Start();
ForLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
}
private static void DoWhileLoop(int max)
{
int i = 0;
do
{
//Performe Some Operation. By removing Speed increases
var j = 10 + 10;
j += 25;
i++;
} while (i <= max);
}
private static void WhileLoop(int max)
{
int i = 0;
while (i <= max)
{
//Performe Some Operation. By removing Speed increases
var j = 10 + 10;
j += 25;
i++;
};
}
private static void ForLoop(int max)
{
for (int i = 0; i <= max; i++)
{
//Performe Some Operation. By removing Speed increases
var j = 10 + 10;
j += 25;
}
}
private static void DisplayElapsedTime(TimeSpan ts)
{
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");
}
}
et voici les résultats d'une Démonstration en direct sur DotNetFiddle :
Boucle Do While :
00:00:00.06Pendant que la boucle est en cours :
00:00:00.13Pour la boucle :
00:00:00.27
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.
9 votes
Mesurez-les si vous le souhaitez (mais ils sont probablement égaux).
5 votes
Je vous parie qu'ils génèrent exactement le même code d'octets.
9 votes
for
dans la plupart des langues est un sucre syntaxique pour un équivalent dewhile
qui est à son tour un sucre syntaxique pour un ensemble d'étiquettes et d'informations.gotos
dans l'assemblage ou l'IL. Compte tenu d'une mise en œuvre efficace de la spécification du langage, ils seront à peu près égaux. Certains langages incluent des "commentaires" internes donnant des indications aux décompilateurs/réflecteurs sur l'aspect du code original, ce qui aura un effet négligeable sur les performances. Je pense que vous constaterez que les plus grandes différences de temps d'exécution sont inhérentes à la programmation du système d'exploitation.13 votes
Il est probablement préférable que vous ne sachiez pas. Si vous utilisez la connaissance d'une possible optimisation prématurée pour influencer votre programmation, en choisissant un code légèrement plus rapide que la conception la plus lisible avant même de savoir si vous avez besoin de cette vitesse, vous échouez.
0 votes
En C : vous pouvez également comparer leur sortie asm :
gcc -S mycsource.c