Juste un coup d'oeil sur le code d'octets avec javap -c [ClassName]
. Voici une classe montrant quelques exemples de variables à usage unique avec des boucles. La décharge de bytecode est pertinente dans les commentaires:
class HelloWorldLoopsAnnotated {
//
// HelloWorldLoopsAnnotated();
// Code:
// 0: aload_0
// 1: invokespecial #1; //Method java/lang/Object."<init>":()V
// 4: return
////////////////////////////////////////////////////////////////////////////
void stringDeclaredInsideLoop(){
while (true) {
// 0: ldC#2; //String Hello World!
String greeting = "Hello World!";
doNothing(greeting);
}
}
//
// void stringDeclaredInsideLoop();
// Code:
// 0: ldC#2; //String Hello World!
// 2: astore_1
// 3: aload_0
// 4: aload_1
// 5: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 8: goto 0
////////////////////////////////////////////////////////////////////////////
void stringDeclaredOutsideLoop(){
String greeting;
while (true) {
greeting = "Hello World!";
doNothing(greeting);
}
}
//
// void stringDeclaredOutsideLoop();
// Code:
// 0: ldC#2; //String Hello World!
// 2: astore_1
// 3: aload_0
// 4: aload_1
// 5: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 8: goto 0
////////////////////////////////////////////////////////////////////////////
void stringAsDirectArgument(){
while (true) {
doNothing("Hello World!");
}
}
// void stringAsDirectArgument();
// Code:
// 0: aload_0
// 1: ldC#2; //String Hello World!
// 3: invokespecial #3; //Method doNothing:(Ljava/lang/String;)V
// 6: goto 0
////////////////////////////////////////////////////////////////////////////
private void doNothing(String s) {
}
}
stringDeclaredInsideLoop()
et stringDeclaredOutsideLoop()
rendement identique bytecode six instruction. stringDeclaredInsideLoop()
gagne toujours: portée limitée est le meilleur.Après quelques réflexions, je ne vois pas vraiment comment le serrage pourrait affecter les performances: des données identiques dans la pile nécessiteraient des instructions identiques.
stringAsDirectArgument()
, cependant, définit l'opération dans seulement quatre instructions. Les environnements à faible mémoire (par exemple, mon téléphone magnifiquement stupide) peuvent apprécier l'optimisation alors qu'un collègue lisant votre code ne peut pas, alors exercez votre jugement avant de raser les octets de votre code.
Voir le full gist pour plus.
Cette réponse est trompeuse, car elle implique que la variable de référence est allouée une fois à chaque itération, ce qui est * not * vrai. –
@BlueRaja - Danny Pflughoeft: Comme je l'ai dit dans ma réponse, il s'agit simplement de créer une * référence * à un objet, sans allouer l'objet entier lui-même. C'est pourquoi la quantité de mémoire est très faible - car seuls les quelques octets nécessaires pour la référence sont tout ce qui est impliqué. – MAK
Oui, je comprends; mais même cette référence (le pointeur lui-même) n'est allouée qu'une seule fois, ce qui va à l'encontre de ce que la phrase * "allouer/désallouer ne devrait pas affecter de manière significative votre programme" * est implicite. –