Java pour la boucle vs boucle while. Différence de Performance?

supposons que j'ai le code suivant, il y en a trois pour loop pour faire quelque chose. Est-ce qu'il fonctionnerait rapidement si je changeais la boucle la plus externe en boucle while? merci ~

int length = 200;
int test = 0;
int[] input = new int[10];

for(int i = 1; i <= length; i++) {
    for (int j = 0; j <=length - i; j++) {
        for (int k = 0; k < length - 1; k++) {
            test = test + input[j + k];
        }
    }
}
24
demandé sur jjnguy 2009-07-22 17:56:58

14 réponses

Non, changer le type de boucle n'aurait pas d'importance.

La seule chose qui peut le rendre plus rapide serait d'avoir moins d'imbrication de boucle, et en boucle sur les valeurs.

la seule différence entre une boucle for et une boucle while est la syntaxe pour les définir. Il n'y a pas de différence de performances à tous.

int i = 0;
while (i < 20){
    // do stuff
    i++;
}

Est le même que:

for (int i = 0; i < 20; i++){
    // do Stuff
}

(en fait le for-loop est un peu mieux parce que le i sera hors de portée après la boucle tandis que le i restera dans le cas de boucle while .)

a pour boucle est juste une façon syntaxiquement plus jolie de boucler.

49
répondu jjnguy 2009-07-22 14:26:19

Ce genre de micro-optimisation est inutile.

  • une boucle ne sera pas plus rapide.
  • la structure de boucle est pas votre goulot d'étranglement.
  • optimisez d'abord votre algorithme.
  • mieux encore, ne pas optimiser d'abord. Optimiser fois que vous avez découvert que vous avez vraiment un goulot d'étranglement dans votre algorithme qui n'est pas I/O-dépendant.
27
répondu Bombe 2009-07-22 14:13:30

vous ne pouvez pas l'optimiser en modifiant à tout.

vous pouvez juste augmenter la vitesse très très très très peu en changeant la ligne

for (int k = 0; k < length - 1; k++) {

par

for (int k = 0; k < lengthMinusOne; k++) {

où lengthMinusOne est calculé avant

cette soustraction est en train de calculer presque (200x201/ 2) x (200-1) fois et il est très peu de nombre pour l'ordinateur:)

9
répondu ufukgun 2009-07-22 14:05:58

Quelqu'un a suggéré de tester while vs for boucles, donc j'ai créé un certain code pour tester si les boucles ou pour les boucles étaient plus rapides; en moyenne, plus de 100.000 tests, while boucle était plus rapide ~95% du temps. Je l'ai peut-être mal codé, je suis tout à fait nouveau dans le codage, aussi en considérant que si je n'ai lancé que 10.000 boucles, elles ont fini par être tout à fait égales dans la durée d'exécution.

edit Je n'ai pas changé toutes les valeurs du tableau Quand je suis allé à test pour plus d'essais. Corrigé pour qu'il soit plus facile de changer le nombre d'essais que vous exécutez.

import java.util.Arrays;

class WhilevsForLoops {

 public static void main(String[] args) {

final int trials = 100; //change number of trials
final int trialsrun = trials - 1;

boolean[] fscount = new boolean[trials]; //faster / slower boolean
int p = 0; // while counter variable for for/while timers



while (p <= trialsrun) {
     long[] forloop = new long[trials];
     long[] whileloop = new long[trials];

     long systimeaverage; 
     long systimenow = System.nanoTime();
     long systimethen = System.nanoTime();

     System.out.println("For loop time array : ");
     for (int counter=0;counter <= trialsrun; counter++) {
         systimenow = System.nanoTime();
         System.out.print(" #" + counter + " @");
         systimethen = System.nanoTime();
         systimeaverage = (systimethen - systimenow);
         System.out.print( systimeaverage + "ns |");

         forloop[counter] = systimeaverage; 
     }

     int count = 0;
     System.out.println(" ");
     System.out.println("While loop time array: ");
     while (count <= trialsrun) {
         systimenow = System.nanoTime();
         System.out.print(" #" + count + " @");
         systimethen = System.nanoTime();
         systimeaverage = (systimethen - systimenow);
         System.out.print( systimeaverage + "ns |");

         whileloop[count] = systimeaverage;
         count++;
     }


     System.out.println("===============================================");
     int sum = 0;

     for (int i = 0; i <= trialsrun; i++) {
        sum += forloop[i];
     }

     System.out.println("for loop time average: " + (sum / trials) + "ns");

     int sum1 = 0;

     for (int i = 0; i <= trialsrun; i++) {
         sum1 += whileloop[i];
     }
     System.out.println("while loop time average: " + (sum1 / trials) + "ns");



     int longer = 0;
     int shorter = 0;
     int gap = 0;

     sum = sum / trials;
     sum1 = sum1 / trials; 

     if (sum1 > sum) {
        longer = sum1;
        shorter = sum;
     }
     else {
        longer = sum;
        shorter = sum1;
     }

     String longa;

     if (sum1 > sum) {
        longa = "~while loop~";
     }
     else {
         longa = "~for loop~";
     }

     gap = longer - shorter; 
     System.out.println("The " + longa + " is the slower loop by: " + gap + "ns");
     if (sum1 > sum) {
     fscount[p] = true; }
     else {
         fscount[p] = false;
     }
     p++;
}

    int forloopfc=0;
    int whileloopfc=0;

    System.out.println(Arrays.toString(fscount));

    for(int k=0; k <= trialsrun; k++) {
        if (fscount[k] == true) {
            forloopfc++; }
            else {
                whileloopfc++;}

    }

    System.out.println("--------------------------------------------------");

    System.out.println("The FOR loop was faster: " + forloopfc + " times.");
    System.out.println("The WHILE loop was faster: " + whileloopfc + " times.");
 }

}
6
répondu Sleepy 2012-11-27 07:23:42

même si l'hypothèse de la boucle while étant plus rapide que la boucle for était vraie (et ce n'est pas le cas), les boucles que vous avez dû changer/optimiser ne seraient pas les boucles externes mais les boucles internes, parce que celles-ci sont exécutées plus de fois.

2
répondu fortran 2009-07-22 14:17:05

la différence entre pour et pendant est sémantique :

  • dans une boucle while, vous boucle aussi longtemps que la condition est vraie, qui peut varier beaucoup, parce que vous pourriez, dans votre boucle, modifier des variables en utilisant dans evluating la condition while.
  • habituellement, dans une boucle pour, vous boucle N temps. Ce N peut être variable, mais ne bouge pas jusqu'à la fin de votre boucle N, comme d'habitude les développeurs ne modifient pas les variables évalué dans la condition de boucle.

C'est un moyen d'aider les autres à comprendre votre code. Vous n'êtes pas obligé de ne pas modifier les variables de boucle, mais c'est une pratique courante (et bonne).

2
répondu Clement Herreman 2009-07-22 14:29:16

voici une lien pour un article sur le sujet

selon lui, le temps et pour sont presque deux fois plus rapides, mais les deux sont les mêmes.

mais cet article a été écrit en 2009 et donc je l'ai essayé sur ma machine et voici les résultats:

  • utilisant java 1.7: L'itérateur était d'environ 20% -30% plus rapide que pour et tandis que (qui étaient toujours les mêmes)
  • utilisant java 1.6: L'itérateur était d'environ 5% plus rapide que pour et tandis que (qui étaient toujours les mêmes)

donc je suppose que la meilleure chose est de le chronométrer sur votre propre version et machine et de conclure à partir de cela

2
répondu levtatarov 2012-04-18 12:38:08

Non, vous êtes toujours en boucle le même nombre de fois. N'importe pas.

1
répondu aquinas 2009-07-22 13:59:22

Regardez votre algorithme! Savez-vous à l'avance quelles valeurs de votre tableau sont ajoutées plus d'une fois?

si vous savez que vous pourriez réduire le nombre de boucles et que cela se traduirait par une meilleure performance.

1
répondu Roalt 2009-07-22 14:05:18

cela n'a d'importance que si vous utilisez la programmation multi-thread ou multi-processeur. Cela dépend alors aussi de la façon dont vous assignez les boucles aux différents processeurs/threads.

0
répondu Extrakun 2009-07-22 14:02:53

Il n'y aurait pas de différence de performances. L'essayer!

le JVM et en outre, le compilateur, ferait des deux boucles quelque chose comme

    label:
       ;code inside your for loop.
    LOOP label
0
répondu Adrian 2011-12-16 18:53:48

Quelqu'un a essayé comme ça...

int i = 20;
while (--i > -1){
    // do stuff
}

par rapport à:

for (int i = 0; i < 20; i++){
    // do Stuff
}
0
répondu Danilo Castro 2016-07-07 09:34:32

basé sur ceci: https://jsperf.com/loops-analyze (Non créé par moi) la boucle while est 22% plus lente que a pour la boucle en général. Au moins en Javascript, il est.

0
répondu Arash R 2017-07-21 16:07:10