50 votes

Qui boucle a une meilleure performance? Pourquoi?

String s = "";
for(i=0;i<....){
    s = some Assignment;
}

ou

for(i=0;i<..){
    String s = some Assignment;
}

Je n'ai pas besoin d'utiliser le 's' en dehors de la boucle. La première option est peut-être mieux, puisqu'une nouvelle Chaîne n'est pas initialisé à chaque fois. La deuxième toutefois entraînerait la portée de la variable qui est limitée à la boucle elle-même.

EDIT: En réponse à Milhous de réponse. Il serait inutile d'affecter la Chaîne à une constante au sein d'une boucle ne serait-il pas? Non, ici, "certains d'Attribution" s'entend d'une évolution de la valeur obtenu à partir de la liste itérée à travers.

Aussi, la question n'est pas parce que je suis inquiet à propos de la gestion de la mémoire. Je veux juste savoir ce qui est mieux.

108voto

erickson Points 127945

De Portée limitée, qui est le Mieux

Utilisez votre seconde option:

for ( ... ) {
  String s = ...;
}

Champ d'application N'Affecte pas les Performances

Si vous démontez le code compilé à partir de chacun (avec le JDK de l' javap outil), vous verrez que la boucle compile à la même JVM instructions dans les deux cas. Notez également que Brian R. Bondy est "l'Option #3" est identique à l'Option #1. Rien de plus est ajouté ou retiré de la pile lors de l'utilisation du resserrement de la portée, et les mêmes données sont utilisées sur la pile dans les deux cas.

D'Éviter L'Initialisation

La seule différence entre les deux cas est que, dans le premier exemple, la variable s est inutilement initialisé. C'est une question distincte de l'emplacement de la déclaration de la variable. Cela ajoute deux gaspillage d'instructions (pour charger une constante de chaîne et de le stocker dans un cadre de pile fente). Un bon outil d'analyse statique va vous avertir que vous n'êtes jamais à la lecture de la valeur que vous attribuez à s, et un bon compilateur JIT sera probablement éluder lors de l'exécution.

Vous pouvez résoudre ce problème en utilisant simplement un vide déclaration (c'est à dire, String s;), mais cela est considéré comme une mauvaise pratique et a un autre effet secondaire discuté ci-dessous.

Souvent une fausse valeur, comme null est affectée à une variable simplement de faire taire une erreur de compilateur que la variable est lue sans être initialisé. Cette erreur peut être pris comme un indice que la portée des variables est trop grand, et qu'il est déclaré avant, il est nécessaire de recevoir une valeur valide. Des déclarations vides de vous forcer à tenir compte de tous code de la route; ne pas ignorer cette précieuse mise en garde par l'attribution d'une fausse valeur.

Économiser La Pile De Fentes

Comme mentionné, alors que la JVM instructions sont les mêmes dans les deux cas, il y a un subtil effet de bord qui le rend meilleur, au niveau de la JVM, à utiliser le plus de portée limitée possible. Ceci est visible dans la "variable locale" de table pour la méthode. Examinons ce qui se passe si vous avez de multiples boucles, avec les variables déclarées dans inutilement grande portée:

void x(String[] strings, Integer[] integers) {
  String s;
  for (int i = 0; i < strings.length; ++i) {
    s = strings[0];
    ...
  }
  Integer n;
  for (int i = 0; i < integers.length; ++i) {
    n = integers[i];
    ...
  }
}

Les variables s et n pourrait être déclarée à l'intérieur de leurs respectifs des boucles, mais depuis ils ne le sont pas, le compilateur utilise deux "trous" dans le cadre de la pile. S'ils ont été déclarés à l'intérieur de la boucle, le compilateur peut réutiliser le même logement, faire la trame de pile plus petite.

Ce Qui Compte Vraiment

Cependant, la plupart de ces questions sont négligeables. Un bon compilateur JIT verrez qu'il n'est pas possible de lire la valeur initiale vous sont inutilement l'affectation, et d'optimiser l'affectation de l'écart. L'enregistrement d'un logement d'ici ou là ne va pas faire ou casser votre application.

La chose importante est de rendre votre code lisible et facile à entretenir, et à cet égard, l'utilisation d'une portée limitée à l'est nettement mieux. Le plus petit de la portée d'une variable a, plus il est facile de comprendre comment il est utilisé et quel est l'impact de tout changement du code.

22voto

Esteban Araya Points 12496

En théorie, c'est un gaspillage de ressources à déclarer la chaîne à l'intérieur de la boucle. Dans la pratique, toutefois, les deux extraits de la présentation de compiler vers le bas pour le même code (déclaration à l'extérieur de la boucle).

Donc, si votre compilateur n'importe quel montant d'optimisation, il n'y a pas de différence.

17voto

Greg Hewgill Points 356191

En général, j'opte pour la deuxième, parce que le champ d'application de la 's' variable est limitée à la boucle. Avantages:

  • C'est mieux pour le programmeur parce que vous n'avez pas à vous soucier de 's' à être utilisé de nouveau quelque part plus tard dans la fonction
  • C'est mieux pour le compilateur, car la portée de la variable est plus petite, et donc peut-être de faire plus d'analyse et d'optimisation
  • C'est mieux pour les futurs lecteurs, parce qu'ils ne pas se demander pourquoi le " s " de la variable est déclarée en dehors de la boucle si elle n'est jamais utilisé plus tard

6voto

GHad Points 4131

Si vous voulez accélérer pour les boucles, je préfère déclarer une variable max à côté du compteur de sorte qu'aucune répétition des recherches pour la condidtion sont nécessaires:

au lieu de

for (int i = 0; i < array.length; i++) {
  Object next = array[i];
}

Je préfère

for (int i = 0, max = array.lenth; i < max; i++) {
  Object next = array[i];
}

Toutes les autres choses qui devraient être considérées ont déjà été citées, juste mes deux cents (voir ericksons post)

Greetz, GHad

4voto

1800 INFORMATION Points 55907

Pour ajouter un peu de @Esteban Araya de réponse, ils nécessitent la création d'une nouvelle chaîne à chaque fois à travers la boucle (comme la valeur de retour de l' some Assignment expression). Ces cordes doivent être nettoyés de toute façon.

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