50 votes

Quelle boucle est la plus rapide, while ou for ?

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 ?

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 de while 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.

3voto

nmichaels Points 21955

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.

3voto

Alpha G33k Points 1057

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.

2voto

AttackingHobo Points 261

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.

1voto

Kurt Bussche Points 1

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.

1voto

Mohit Dhawan Points 329

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.06

Pendant que la boucle est en cours :
00:00:00.13

Pour la boucle :
00:00:00.27

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