En Java est-il une différence de performance entre le référencement d'un champ par rapport à getter par une variable?

StackOverflow https://stackoverflow.com/questions/1195849

Question

Y at-il des différences entre faire

Field field = something.getSomethingElse().getField();
if (field == 0) {
//do something    
}
somelist.add(field);

contre

if (something.getSomethingElse().getField() == 0) {
//do something    
}
somelist.add(something.getSomethingElse().getField());

Faites des références sur le terrain par getters encourent une pénalité de performance ou est-ce le même que référence à une variable assignée? Je comprends que la variable est juste une référence à l'espace de mémoire, de sorte que le getter devrait être juste une autre façon d'obtenir à l'espace mémoire.

Notez que ceci est une question académique (école de curieux) plutôt que d'ordre pratique.

Était-ce utile?

La solution

En supposant que getSomethingElse() est définie comme

public SomethingElse getSomethingElse() {
    return this.somethingElse;
}

différence de performance sera minime (ou zéro si ça va s'inline). Cependant, dans la vraie vie, vous ne pouvez pas toujours être sûr que ce soit le cas - il peut y avoir un traitement qui se passe dans les coulisses (pas nécessairement dans l'objet lui-même mais, par exemple, par l'intermédiaire de proxy AOP). Donc, sauvegarder le résultat dans la variable d'accès répétition peut être une bonne idée.

Autres conseils

Il est un préjudice négligeable. Ne vous préoccupez pas de trop ou vous allez tomber en proie à l'optimisation prématurée. Si votre application est lente, ce n'est pas la raison pour laquelle.

Il y a une différence dans les variables que les accès par les résultats getters dans un appel de méthode. La machine virtuelle Java pourrait éventuellement être en mesure d'optimiser l'appel de méthode loin dans certaines circonstances, mais est un appel de méthode.

Cela dit, si le plus gros goulot d'étranglement ou d'un problème dans la performance de votre code est en tête de méthodes accesseurs, je dirais que vous n'avez pas beaucoup à se soucier.

Il y a une pénalité de performance (qui peut être si petit qu'il est négligeable) Cependant, la machine virtuelle Java peut inline cela et tous les appels pour améliorer les performances.

Il serait mieux si vous laissez la deuxième voie.

Pas si vous avez une bonne machine virtuelle Java, comme HotSpot de Sun. Il sera en ligne et compiler (en code natif) les getters.

L'utilisation getters est généralement une très bonne pratique, comme une mesure défensive, géneraux Hiding.

Un point à noter si l'utilisation de Java pour écrire des applications Android est ici: http://developer.android.com/training/articles/perf-tips .html # GettersSetters

  

Dans les langues indigènes comme C ++, il est pratique courante d'utiliser getters (i =   getCount ()) au lieu d'accéder directement à la zone (i = mcount). Cette   est une excellente habitude pour C ++ et est souvent pratiqué dans un autre objet   langages orientés comme C # et Java, parce que le compilateur peut généralement   inline l'accès, et si vous avez besoin de restreindre ou d'accès aux champs de débogage   vous pouvez ajouter le code à tout moment.

     

Cependant, cela est une mauvaise idée sur Android. appels de méthodes virtuelles sont   cher, bien plus que sur le terrain de lookups exemple. Il est raisonnable   de suivre les pratiques de programmation orientées objet commun et ont   accesseurs dans l'interface publique, mais au sein d'une classe que vous   devrait toujours accéder aux champs directement.

     

Sans JIT, un accès direct sur le terrain est environ 3 fois plus rapide que d'invoquer un   getter trivial. Avec le JIT (où l'accès direct sur le terrain est aussi pas cher que   l'accès à un local), accès direct aux champs est d'environ 7x plus rapide que   invoquant un getter trivial.

     

Notez que si vous utilisez ProGuard, vous pouvez avoir le meilleur des deux   mondes parce ProGuard peuvent inline accesseurs pour vous.

Si la méthode est une méthode de lecture simple, sans traitement en jeu, il est pas un problème. Si elle implique une vaste calcul, une propriété ne serait pas faire ce que vous voulez de toute façon.

La seule fois où je me inquiéterais toute différence est dans une boucle serrée avec un grand nombre d'itérations (plusieurs milliers). Même alors c'est probablement un problème si vous utilisez des aspects pour tisser un traitement supplémentaire (par exemple l'exploitation forestière), cela peut impliquer la création de milliers d'objets supplémentaires (par exemple joinpoints et paramètres Autoboxing) et résultant des problèmes de GC.

Je ne vous inquiétez pas au sujet de la différence de performance. Vous feriez mieux de ne pas penser et passer à la place du temps sur le profilage de votre code dans un scénario réaliste. Vous trouverez plus probable que les parties lentes de votre programme ne sont pas où vous pensez qu'ils sont.

pourparlers de poste sur la CLI VM au lieu de la machine virtuelle Java, mais chacun est capable de faire des choses semblables, donc je crois qu'il est pertinent.

Je me occupe ce problème d'une manière particulière pour mon JIT. Notez que la description ici est d'ordre conceptuel et le code, il met en œuvre d'une manière légèrement différente pour des raisons de performance. Quand je charge un ensemble, je fais une note dans le descripteur de méthode si elle retourne simplement un champ membre. Quand je JIT d'autres méthodes plus tard, je remplace toutes les instructions de call à ces méthodes dans le code d'octets avec une instruction de ldfld avant de le transmettre au générateur de code natif. De cette façon, je peux:

  1. gagner du temps dans le JIT (ldfld prend moins de temps de traitement à JIT que call).
  2. propriétés Inline même dans le base compilateur .
  3. En gros garantie que l'utilisation du modèle propriétés publiques / privées champs n'encourt une pénalité de performance de quelque nature que lorsque le débogueur est détaché. (Quand un débogueur est attaché, je ne peux pas inline accesseurs.)

Je ne doute pas que les grands noms des technologies VM appliquent déjà quelque chose de similaire (et probablement mieux) que cela dans leurs produits.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top