[Java] Question philosophique:declaration de variable dans une boucle

Question philosophique:declaration de variable dans une boucle [Java] - Programmation

Marsh Posté le 05-04-2002 à 17:07:18    

Y'a plus ou moins unanimite dans la communaute Java pour dire que declarer une variable dans une boucle c'est mal (tm) ... est ce que quelqu'un connait la justification de cette regle ?  
 
(ce n'est pas un probleme de perfs puisque apres verif le bytecode genere est identique ... plutot un truc de qualite de code, maintenance, testabilite ou un truc du genre)
 
Exemple de ce qu'il faudrait eviter :
 
while ( ... ) {
 String a = ...
}
 
mais plutot:
 
string a = ...  
while ( ... ) {
 a = ...
}

Reply

Marsh Posté le 05-04-2002 à 17:07:18   

Reply

Marsh Posté le 05-04-2002 à 17:13:21    

Comment !
 
On peut faire CA en Java !
 
J'croyais que c'était un language Sérieux . . .


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 05-04-2002 à 17:13:59    

Ben à chaque passage dans ta boucle, tu demandes à la JVM de récréer un objet, c'est pourri comme manière.

Reply

Marsh Posté le 05-04-2002 à 17:14:22    

Mara's dad a écrit a écrit :

Comment !
 
On peut faire CA en Java !
 
J'croyais que c'était un language Sérieux . . .  



Vilain, je le dirais à Mara.

Reply

Marsh Posté le 05-04-2002 à 17:34:11    

Cherrytree a écrit a écrit :

Ben à chaque passage dans ta boucle, tu demandes à la JVM de récréer un objet, c'est pourri comme manière.  




 
Le code genere est le meme, donc c'est pas un prob de performances ... c'est au niveau du code lui-meme que c'est pas top, mais pourquoi ? (je suis un integriste des regles de programmation mais la je seche)

Reply

Marsh Posté le 05-04-2002 à 17:40:29    

Gonzoide a écrit a écrit :

 
 
Le code genere est le meme, donc c'est pas un prob de performances ... c'est au niveau du code lui-meme que c'est pas top, mais pourquoi ? (je suis un integriste des regles de programmation mais la je seche)  



Tu veux dire que javac donne strictement le même bytecode ?

Reply

Marsh Posté le 05-04-2002 à 17:41:47    

Cà fait même 2 fois qu'il le dit !


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 05-04-2002 à 17:48:24    

Ouais je me repete, mais j'avais bien vu que le message passait pas :)
 
Donc c'est philosophiquement pas beau ... mais pourquoi ?

 

[jfdsdjhfuetppo]--Message édité par Gonzoide--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 05-04-2002 à 17:51:33    

OK ! J'avais mal lu. J'espère répondre à ta question cette fois : je pense que c'est effectivement pourri pour la raison que je t'ai apportée plus haut (d'un point de vue sémantique, hein !), mais que javac est pas con et qu'il optimise ton code tout pourri. Essaye de décompiler ton app, pour voir, si je ne me trompe pas.

Reply

Marsh Posté le 05-04-2002 à 17:52:58    

Mara's dad a écrit a écrit :

Cà fait même 2 fois qu'il le dit !  




 
la vraie question, c'est est ce que ca fait le même bytecode avec un cas un peu plus compliqué :  
 
for (int i = 1; i < 100; i++) {
   if ((int) (Math.random() * 10000000) == 666) {
      String s = "Si la JVM reserve l'espace pour cette chaine avant la boucle, c'est con ...";
   }
}

Reply

Marsh Posté le 05-04-2002 à 17:52:58   

Reply

Marsh Posté le 05-04-2002 à 17:55:30    

Cherrytree a écrit a écrit :

OK ! J'avais mal lu. J'espère répondre à ta question cette fois : je pense que c'est effectivement pourri pour la raison que je t'ai apportée plus haut (d'un point de vue sémantique, hein  




Ouais mais c'est un peu leger comme argument :)

Cherrytree a écrit a écrit :

Essaye de décompiler ton app, pour voir, si je ne me trompe pas.  




C'est ce que j'ai fait bien sur pour pouvoir dire que le bytecode etait le meme dans les deux cas

Reply

Marsh Posté le 05-04-2002 à 17:56:53    

Gonzoide a écrit a écrit :

 
C'est ce que j'ai fait bien sur pour pouvoir dire que le bytecode etait le meme dans les deux cas  



:heink:

Reply

Marsh Posté le 05-04-2002 à 17:59:13    

Ben c'est un principe de base pour tous les langages je pense, on déclare les variables en début de procedure pour une meilleure lisibilité (toutes les déclarations sont regroupées)


---------------
"I wonder if the internal negative pressure in self pumping toothpaste tubes is adjusted for different market altitudes." John Carmack
Reply

Marsh Posté le 05-04-2002 à 18:03:18    

Et puis comme ça, les compilateurs (traditionnels, tout bête) savent combien de mémoire allouer. Pour un if par exemple :

Code :
  1. if (b == true) {
  2.       String s = "Coucou";
  3. } else {
  4.       //do nothing
  5. }


Suivant le cas, il y a ou non allocation de mémoire.

Reply

Marsh Posté le 05-04-2002 à 18:10:26    

t sur que c pas ton decompilateur qui decompile de la meme maniere  dans les deux cas ?
 
paske les .class générés sont différents eux

Reply

Marsh Posté le 05-04-2002 à 18:17:09    

HappyHarry a écrit a écrit :

t sur que c pas ton decompilateur qui decompile de la meme maniere  dans les deux cas ?
 
paske les .class générés sont différents eux  



Ahhhhh, voilà une intervention qu'elle est bonne.

Reply

Marsh Posté le 05-04-2002 à 18:19:59    

HappyHarry a écrit a écrit :

t sur que c pas ton decompilateur qui decompile de la meme maniere  dans les deux cas ?
 
paske les .class générés sont différents eux  




 
J'attendais la question :D C'est vrai, mais les "bytecodes decompiles" sont identiques (les differences de .class sont dues aux noms de classes qui sont differents, et qui sont stockees dans le .class) :
 
JAVA 1  
 
import java.util.Date;
 
public class RefInLoop {
    private static final int NB_OF_LOOPS = 10;
     
    public static void main(String[] args) {
        int i = 0;
 
 for(i = 0 ; i < NB_OF_LOOPS ; i++) {
           String suchARef = getString();
 
    System.out.println(suchARef);   //mandatory to avoid the discard of the loop
 }
        System.out.println("Outside the loop" );
    }
     
    private static String getString() {
 return new Date().toString();
    }
 
}
 
BYTECODE 1
 
Compiled from RefInLoop.java
public class RefInLoop extends java.lang.Object {
    public RefInLoop();
    public static void main(java.lang.String[]);
}
 
Method RefInLoop()
   0 aload_0
   1 invokespecial #1 <Method java.lang.Object()>
   4 return
 
Method void main(java.lang.String[])
   0 iconst_0
   1 istore_1
   2 iconst_0
   3 istore_1
   4 goto 21
   7 invokestatic #2 <Method java.lang.String getString()>
  10 astore_2
  11 getstatic #3 <Field java.io.PrintStream out>
  14 aload_2
  15 invokevirtual #4 <Method void println(java.lang.String)>
  18 iinc 1 1
  21 iload_1
  22 bipush 10
  24 if_icmplt 7
  27 getstatic #3 <Field java.io.PrintStream out>
  30 ldc #5 <String "Outside the loop">
  32 invokevirtual #4 <Method void println(java.lang.String)>
  35 return
 
Method java.lang.String getString()
   0 new #6 <Class java.util.Date>
   3 dup
   4 invokespecial #7 <Method java.util.Date()>
   7 invokevirtual #8 <Method java.lang.String toString()>
  10 areturn
 
DECOMPIL 1
 
import java.io.PrintStream;
import java.util.Date;
 
public class RefInLoop
{
 
    public RefInLoop()
    {
    }
 
    public static void main(String args[])
    {
        int i = 0;
        for(i = 0; i < 10; i++)
        {
            String suchARef = getString();
            System.out.println(suchARef);
        }
 
        System.out.println("Outside the loop" );
    }
 
    private static String getString()
    {
        return (new Date()).toString();
    }
 
    private static final int NB_OF_LOOPS = 10;
}
 
JAVA 2
 
import java.util.Date;
 
public class RefOutsideLoop {
    private static final int NB_OF_LOOPS = 10;
     
    public static void main(String[] args) {
        int i = 0;
        String suchARef;
 
 for(i = 0 ; i < NB_OF_LOOPS ; i++) {
    suchARef= getString();
 
    System.out.println(suchARef);   //mandatory to avoid the discard of the loop
 }
        System.out.println("Outside the loop" );
    }
     
    private static String getString() {
 return new Date().toString();
    }
 
}
 
BYTECODE 2
 
public class RefOutsideLoop extends java.lang.Object {
    public RefOutsideLoop();
    public static void main(java.lang.String[]);
}
 
Method RefOutsideLoop()
   0 aload_0
   1 invokespecial #1 <Method java.lang.Object()>
   4 return
 
Method void main(java.lang.String[])
   0 iconst_0
   1 istore_1
   2 iconst_0
   3 istore_1
   4 goto 21
   7 invokestatic #2 <Method java.lang.String getString()>
  10 astore_2
  11 getstatic #3 <Field java.io.PrintStream out>
  14 aload_2
  15 invokevirtual #4 <Method void println(java.lang.String)>
  18 iinc 1 1
  21 iload_1
  22 bipush 10
  24 if_icmplt 7
  27 getstatic #3 <Field java.io.PrintStream out>
  30 ldc #5 <String "Outside the loop">
  32 invokevirtual #4 <Method void println(java.lang.String)>
  35 return
 
Method java.lang.String getString()
   0 new #6 <Class java.util.Date>
   3 dup
   4 invokespecial #7 <Method java.util.Date()>
   7 invokevirtual #8 <Method java.lang.String toString()>
  10 areturn
 
 
DECOMPIL 2
 
import java.io.PrintStream;
import java.util.Date;
 
public class RefOutsideLoop
{
 
    public RefOutsideLoop()
    {
    }
 
    public static void main(String args[])
    {
        int i = 0;
        for(i = 0; i < 10; i++)
        {
            String suchARef = getString();
            System.out.println(suchARef);
        }
 
        System.out.println("Outside the loop" );
    }
 
    private static String getString()
    {
        return (new Date()).toString();
    }
 
    private static final int NB_OF_LOOPS = 10;
}

 

[jfdsdjhfuetppo]--Message édité par Gonzoide--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 05-04-2002 à 18:23:20    

Gonzoide a écrit a écrit :

 
 
J'attendais la question :D C'est vrai, mais les "bytecodes decompiles" sont identiques (les differences de .class sont dues aux noms de classes qui sont differents, et qui sont stockees dans le .class) :




 
perdu j'ai utilisé EXACTEMENT le meme code (meme nom de classe) , dans le 2e j'ai juste sorti la declaration de la variable de la boucle   :D

Reply

Marsh Posté le 05-04-2002 à 18:25:43    

Ben j'ai pas fait (faire ;)) mon test dans les memes conditions ... mais je me dis que le plus important c'est quand meme le "bytecode decompile" (je sais pas comment dire autrement), qui est l'equivalent du desassemblage, donc un mapping 1-1 entre ce qui est execute et ce qui est lisible ... le reste, c'est du sucre syntaxique :)
 
PS : Ca se trouve c'est la date et heure de compil qui est stockee dans le .class, va savoir :)

Reply

Marsh Posté le 05-04-2002 à 18:27:28    

bon ben j'vais tester aussi alors ... t'as utilisé koi pour décompiler ?

Reply

Marsh Posté le 05-04-2002 à 19:14:40    

:??:

Reply

Marsh Posté le 05-04-2002 à 20:03:01    

Jad, pile-poil

Reply

Marsh Posté le 05-04-2002 à 20:05:59    

la page de dl est down  :(

Reply

Marsh Posté le 05-04-2002 à 20:34:27    

Je l'ai pas ici :(

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed