y a-t-il des différences entre faire
if (something.getSomethingElse().getField() == 0) { //do something } somelist.add(something.getSomethingElse().getField());
9 Réponses :
C'est un préjudice négligeable. Ne vous inquiétez pas avec trop ou vous allez tomber en proie à une optimisation prématurée. Si votre demande est lente, ce n'est pas la raison pour laquelle. p>
Il y a une pénalité de performance (ce qui peut être si petit qu'il est négligeable), le JVM peut en ligne et tous les appels pour améliorer la performance. P>
Ce serait mieux si vous le laissez la deuxième manière. p>
Sans parler de la deuxième manière est plus lisible et est moins de code.
Pas si vous avez un bon JVM, comme Hotspot de Sun. Il sera en ligne et compilera (au code natif) les getters. P>
L'utilisation de getters est généralement une très bonne pratique, comme une mesure défensive et des informations générales se cachent. P>
Il y a une différence dans cet accès aux variables via des résultats obtenus dans un appel de méthode. La JVM pourrait éventuellement pouvoir optimiser la méthode appelle dans certaines circonstances, mais est em> un appel de méthode. P>
Cela dit, si le plus grand goulot d'étranglement ou le plus grand problème de performance de votre code est surchargé des méthodes d'accesseur, je dirais que vous n'avez pas beaucoup à craindre. P>
En supposant que différence de performance sera minimal (ou zéro si elle sera inline). Cependant, dans la vie réelle, vous ne pouvez pas toujours être sûr que c'est le cas - il peut y avoir un certain traitement dans les coulisses (pas nécessairement dans l'objet lui-même, mais, par exemple, via AOP Proxy). Sauvegarde donc le résultat dans la variable pour l'accès répété peut être une bonne idée. P> p> attraytionelse () code> est défini comme
Si la méthode est une simple getter sans traitement impliqué, ce n'est pas un problème. Si cela implique un calcul important, une propriété ne ferait pas ce que vous voulez de toute façon. P>
Le seul moment où je m'inquiéterais de toute différence est dans une boucle serrée avec un grand nombre d'itérations (plusieurs milliers). Même ce n'est probablement qu'un problème que si vous utilisez des aspects pour tisser un traitement supplémentaire (E.G. Logging), cela peut impliquer de créer des milliers d'objets supplémentaires (par exemple les points de jointure et de l'autoboxage des paramètres) et des problèmes de GC résultants. P>
Je ne m'inquiéterais pas de la différence de performance. Vous feriez mieux de ne pas y penser et de passer du temps à profiler votre code dans un scénario réaliste. Vous constaterez probablement que les parties lentes de votre programme ne sont pas là où vous pensez être. P>
Ce message parle de la CLI VM au lieu de la JVM, mais chacun est capable de faire des choses similaires, alors je crois que c'est pertinent. P>
Je gère ce problème particulier de manière particulière pour mon JIT. Notez que la description ici est conceptuelle et que le code l'applique de manière légèrement différente pour des raisons de performance. Lorsque je charge un assemblage, je porte une note dans le descripteur de méthode s'il renvoie simplement un champ de membre. Lorsque je jit d'autres méthodes plus tard, je remplace tous les instructions Je ne doute pas que les grands noms des technologies VM mettent déjà en œuvre quelque chose de similaire à (et probablement mieux que) cela dans leurs produits. P> appelez code> sur ces méthodes dans le code octet avec un instruction
ldfld code> avant de le transmettre au générateur de code natif. De cette façon, je peux: p>
ldfld code> prend moins de temps de processeur sur JIT que
appel code>). LI>
Un point à noter si vous utilisez Java pour écrire des applications Android est ici: http://developer.android.com/training/articles/perf-tips .html # gettersseters p>
dans des langages indigènes comme C ++, il est courant d'utiliser des getters (i = getcount ()) au lieu d'accéder directement au terrain (i = mcount). Cette est une excellente habitude pour C ++ et est souvent pratiquée dans un autre objet langages orientés comme c # et java, car le compilateur peut généralement en ligne l'accès, et si vous devez restreindre ou déboguer un accès sur le terrain Vous pouvez ajouter le code à tout moment. P>
Cependant, c'est une mauvaise idée sur Android. strong> Les appels de méthode virtuelle sont cher, beaucoup plus que des recherches sur le terrain d'instance. C'est raisonnable suivre les pratiques de programmation courantes orientées objet et avoir getters et setters dans l'interface publique, mais dans une classe vous devrait toujours accéder directement aux champs. P> sans JIT, l'accès direct sur le terrain est d'environ 3 fois plus rapidement que d'invoquer un getter trivial. Avec le JIT (où l'accès direct sur le terrain est aussi bon marché que accéder à un local), Accès direct sur le terrain est d'environ 7 fois plus rapidement que invoquant un getter trivial. strong> p>
Notez que si vous utilisez Proguard, vous pouvez avoir le meilleur des deux mondes parce que PROGUARD peut les accesseurs en ligne pour vous. P> blockQuote>
Notez qu'il peut également y avoir une différence entre les deux, si vous travaillez dans un environnement multi-threadé, comme quelque chose.Getsrogethingselse () peut être modifié par d'autres threads pendant la // faire quelque chose en partie. Causer que la valeur ajoutée au somnoliste soit différente entre les deux parties de code.