La portée des variables locales doit toujours être la plus petite possible.
Dans votre exemple, je présume qu'il str
n'est pas utilisé en dehors de la while
boucle, sinon vous ne poseriez pas la question, car le déclarer à l'intérieur de la while
boucle ne serait pas une option, car il ne compilerait pas.
Donc, comme il str
n'est pas utilisé en dehors de la boucle, la plus petite étendue possible pour se str
trouve dans la boucle while.
Donc, la réponse est catégoriquement qui str
doit absolument être déclarée dans la boucle while. Pas de si, pas de and, pas de mais.
Le seul cas où cette règle pourrait être violée est si, pour une raison quelconque, il est d'une importance vitale que chaque cycle d'horloge soit retiré du code, auquel cas vous voudrez peut-être envisager d'instancier quelque chose dans une portée externe et de le réutiliser au lieu de la ré-instanciation à chaque itération d'une portée intérieure. Cependant, cela ne s'applique pas à votre exemple, en raison de l'immuabilité des chaînes en java: une nouvelle instance de str sera toujours créée au début de votre boucle et devra être jetée à la fin de celle-ci, donc là il n'y a aucune possibilité d'optimiser là-bas.
EDIT: (en injectant mon commentaire ci-dessous dans la réponse)
Dans tous les cas, la bonne façon de faire les choses est d'écrire correctement tout votre code, d'établir une exigence de performance pour votre produit, de mesurer votre produit final par rapport à cette exigence, et s'il ne la satisfait pas, alors allez optimiser les choses. Et ce qui finit généralement par se produire, c'est que vous trouvez des moyens de fournir des optimisations algorithmiques agréables et formelles à quelques endroits qui permettent à notre programme de répondre à ses exigences de performances au lieu d'avoir à parcourir toute votre base de code et de modifier et de pirater des choses dans afin de serrer les cycles d'horloge ici et là.
J'ai comparé le code d'octet de ces deux exemples (similaires):
Regardons 1. exemple :
après
javac Test.java
,javap -c Test
vous obtiendrez:Regardons 2. exemple :
après
javac Test.java
,javap -c Test
vous obtiendrez:Les observations montrent qu'il n'y a pas de différence entre ces deux exemples. C'est le résultat des spécifications JVM ...
Mais au nom de la meilleure pratique de codage, il est recommandé de déclarer la variable dans la plus petite portée possible (dans cet exemple, elle est à l'intérieur de la boucle, car c'est le seul endroit où la variable est utilisée).
la source
final
amoureux: déclarerstr
commefinal
dans leinside
cas du paquet ne fait également aucune différence =)La déclaration d'objets dans la plus petite étendue améliore la lisibilité .
Les performances n'ont pas d'importance pour les compilateurs d'aujourd'hui (dans ce scénario)
Du point de vue de la maintenance, la 2e option est meilleure.
Déclarez et initialisez les variables au même endroit, dans la portée la plus étroite possible.
Comme Donald Ervin Knuth l'a dit:
c.-à-d.) situation dans laquelle un programmeur laisse des considérations de performances affecter la conception d'un morceau de code. Cela peut entraîner une conception qui n'est pas aussi propre qu'elle aurait pu l'être ou un code incorrect, car le code est compliqué par l' optimisation et le programmeur est distrait par l' optimisation .
la source
si vous souhaitez également utiliser
str
looop extérieur; le déclarer à l'extérieur. sinon, la 2ème version est très bien.la source
Veuillez passer à la réponse mise à jour ...
Pour ceux qui se soucient des performances, sortez le System.out et limitez la boucle à 1 octet. En utilisant double (test 1/2) et String (3/4), le temps écoulé en millisecondes est indiqué ci-dessous avec Windows 7 Professionnel 64 bits et JDK-1.7.0_21. Les bytecodes (également donnés ci-dessous pour test1 et test2) ne sont pas identiques. J'étais trop paresseux pour tester avec des objets mutables et relativement complexes.
double
Test1 a pris: 2710 ms
Test2 a pris: 2790 ms
String (remplacez simplement double par string dans les tests)
Test3 a pris: 1200 ms
Test4 a pris: 3000 ms
Compilation et obtention du bytecode
RÉPONSE MISE À JOUR
Il n'est vraiment pas facile de comparer les performances avec toutes les optimisations JVM. Cependant, c'est quelque peu possible. Meilleur test et résultats détaillés dans Google Caliper
Code d'essai partiel pour double déclaration
Ce n'est pas identique au code ci-dessus. Si vous codez simplement une boucle factice, la JVM la saute, vous devez donc au moins affecter et renvoyer quelque chose. Ceci est également recommandé dans la documentation de Caliper.
la source
Une solution à ce problème pourrait être de fournir une portée variable encapsulant la boucle while:
Ils seraient automatiquement dé-référence lorsque la portée externe se termine.
la source
A l'intérieur, moins la portée est visible, mieux c'est.
la source
Si vous n'avez pas besoin d'utiliser la
str
boucle after the while (liée à la portée), la deuxième conditionest préférable car si vous définissez un objet sur la pile uniquement si le
condition
est vrai. C'est à dire l'utiliser si vous en avez besoinla source
Je pense que la meilleure ressource pour répondre à votre question serait le message suivant:
Différence entre déclarer des variables avant ou en boucle?
Selon ma compréhension, cette chose dépendrait de la langue. IIRC Java optimise cela, donc il n'y a pas de différence, mais JavaScript (par exemple) fera toute l'allocation de mémoire à chaque fois dans la boucle.
la source
Comme de nombreuses personnes l'ont souligné,
n'est PAS mieux que ça:
Ne déclarez donc pas de variables en dehors de leur portée si vous ne les réutilisez pas ...
la source
Déclarer String str en dehors de la boucle wile permet de le référencer à l'intérieur et à l'extérieur de la boucle while. La déclaration de String str à l'intérieur de la boucle while permet de la référencer uniquement à l'intérieur de la boucle while.
la source
Les variables doivent être déclarées aussi près que possible de leur utilisation.
Il facilite le RAII (Resource Acquisition Is Initialization) .
Il maintient l'étendue de la variable étroite. Cela permet à l'optimiseur de mieux fonctionner.
la source
Selon le guide de développement de Google Android, la portée variable devrait être limitée. Veuillez vérifier ce lien:
Limiter la portée variable
la source
La
str
variable sera disponible et réservera de l'espace en mémoire même après avoir été exécutée sous le code.La
str
variable ne sera pas disponible et également la mémoire sera libérée qui a été allouée pour lastr
variable dans le code ci-dessous.Si nous avons suivi le deuxième, cela réduira sûrement la mémoire de notre système et augmentera les performances.
la source
La déclaration à l'intérieur de la boucle limite la portée de la variable respective. Tout dépend de l'exigence du projet sur l'étendue de la variable.
la source
Vraiment, la question énoncée ci-dessus est un problème de programmation. Comment souhaitez-vous programmer votre code? Où avez-vous besoin d'accéder au «STR»? Il est inutile de déclarer une variable qui est utilisée localement comme variable globale. Les bases de la programmation je crois.
la source
Ces deux exemples aboutissent à la même chose. Cependant, le premier vous permet d'utiliser la
str
variable en dehors de la boucle while; le second ne l'est pas.la source
Avertissement pour presque tout le monde dans cette question: voici un exemple de code où à l'intérieur de la boucle, il peut facilement être 200 fois plus lent sur mon ordinateur avec Java 7 (et la consommation de mémoire est également légèrement différente). Mais c'est une question d'allocation et pas seulement de portée.
Conclusion: Selon la taille de la variable locale, la différence peut être énorme, même avec des variables moins importantes.
Juste pour dire que parfois, à l'extérieur ou à l'intérieur de la boucle, c'est important.
la source
bigStuff[(int) (value % STUFF_SIZE)] = value;
(Essayez une valeur de 2147483649L)Je pense que la taille de l'objet est également importante. Dans l'un de mes projets, nous avions déclaré et initialisé un grand tableau bidimensionnel qui faisait que l'application rejetait une exception de mémoire insuffisante. Nous avons plutôt déplacé la déclaration hors de la boucle et effacé le tableau au début de chaque itération.
la source
Vous risquez de voir
NullPointerException
si votrecalculateStr()
méthode retourne null , puis vous essayez d'appeler une méthode sur str.Plus généralement, évitez d'avoir des variables avec une valeur nulle . Il est plus fort pour les attributs de classe, soit dit en passant.
la source
NullPointerException.
si ce code tentait dereturn str;
rencontrer une erreur de compilation.