In Java gibt es einen Unterschied in der Leistung ein Feld durch Getter gegenüber durch eine Variable zwischen werben?

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

Frage

Gibt es irgendwelche Unterschiede zwischen tun

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

Vergleich

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

Verweise auf das Feld durch Getter entstehen eine Leistungseinbuße oder ist es das gleiche wie eine zugewiesene Variable werben? Ich verstehe, dass der Variable auf den Speicherplatz nur eine Referenz ist, so dass der Getter sollte nur eine andere Art und Weise sein, in diesem Speicherplatz zu erhalten.

Beachten Sie, dass es sich um eine akademische Frage (Schule von nur neugierig) eher dann einem praktischen.

War es hilfreich?

Lösung

Unter der Annahme, dass getSomethingElse() ist definiert als

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

Performance-Unterschied minimal sein (oder Null, wenn es inlined erhalten werden). Doch im wirklichen Leben kann man nicht immer sicher sein, dass der Fall ist - kann es einige Verarbeitung hinter den Kulissen (nicht unbedingt in dem Objekt selbst, sondern, sagen wir, über AOP-Proxy) passiert sein. So kann durch Speichern Sie das Ergebnis in der Variablen für Wiederholungs Zugang eine gute Idee sein.

Andere Tipps

Es ist ein vernachlässigbarer Nachteil. Beschäftigen Sie sich nicht mit ihm zu viel, oder Sie werden zum Opfer fallen vorzeitige Optimierung. Wenn Ihre Anwendung langsam ist, ist dies nicht der Grund, warum.

Es gibt einen Unterschied, dass der Zugriff auf Variablen durch Getter Ergebnisse in einem Methodenaufruf. Die JVM könnte möglicherweise der Lage sein, den Methodenaufruf zu optimieren weg unter Umständen, aber es is ein Methodenaufruf.

sagte, dass, wenn der größte Engpass oder Performance-Problem in Ihrem Code-Overhead von Accessormethoden ist, würde ich sagen, dass Sie nicht viel zu befürchten.

Es gibt eine Leistungseinbuße (die so klein sein, kann es zu vernachlässigen ist) Doch die JVM diese und alle Anrufe Inline kann die Leistung zu verbessern.

Es wäre besser, wenn Sie es den zweiten Weg verlassen.

Nicht, wenn Sie eine gute JVM, wie HotSpot von Sun. Es wird in-line und Kompilierung (zu nativen Code) den Getter.

Getter Verwendung ist in der Regel eine sehr gute Praxis, als Abwehrmaßnahme und allgemeine Information Hiding.

Ein Punkt ist zu beachten, wenn mit Hilfe von Java-Anwendungen für Android schreiben, ist hier: http://developer.android.com/training/articles/perf-tips .html # GettersSetters

  

In Muttersprachen wie C ++ ist es gängige Praxis, die Verwendung Getter (i =   getCount ()) statt, das Feld unmittelbar von Zugriff (i = MCOUNT). Diese   ist eine ausgezeichnete Gewohnheit für C ++ und wird oft in anderem Objekt praktiziert   orientierte Sprachen wie C # und Java, da der Compiler kann in der Regel   Inline den Zugang, und wenn Sie benötigen, zu beschränken oder zu debuggen Feldzugriff   Sie können den Code jederzeit hinzufügen.

     

Dies ist jedoch eine schlechte Idee auf Android. Virtuelle Methodenaufrufe sind   teuer, viel mehr als Instanzfeld Lookups. Es ist vernünftig   zu folgen gemeinsame objektorientierte Programmiertechniken und haben   Getter und Setter in der öffentlichen Schnittstelle, sondern innerhalb einer Klasse, die Sie   sollte immer direkt Zugang Felder aus.

     

Ohne JIT, Direktfeld ist etwa 3x schneller als ein Aufruf   Trivial Getter. Mit der JIT (wo direktem Feldzugriff ist so billig wie   Zugriff auf eine lokale), Zugriff Direktfeld ist ca. 7x schneller als   ein trivial Getter aufgerufen wird.

     

Beachten Sie, dass, wenn Sie ProGuard verwenden, können Sie das Beste aus beiden haben   Welten, weil ProGuard kann Accessoren für Sie inline.

Wenn die Methode ein einfaches Getter ohne Verarbeitung ist beteiligte es kein Problem ist. Wenn es umfangreiche Berechnung beinhaltet, würde eine Eigenschaft nicht tun, was Sie wollen auf jeden Fall.

Das einzige Mal, dass ich über jeden Unterschied sorgen würde, ist in einer engen Schleife mit einer großen Anzahl von Iterationen (viele Tausend). Selbst dann ist dies wahrscheinlich nur ein Problem, wenn man Aspekte verwendet zusätzliche Verarbeitung zu weben (z logging), diese beinhalten können Tausende von zusätzlichen Objekten (z JoinPoints und Parameter Autoboxing) und die daraus resultierende GC Probleme zu schaffen.

Ich würde nicht über den Performance-Unterschied sorgen. Sie wäre besser, nicht darüber nachdenken und stattdessen Zeit damit verbringen, auf Ihren Code in einem realistischen Szenario Profilierung. Sie werden wahrscheinlich feststellen, dass die langsamen Teile des Programms sind nicht da, wo Sie denken, sie sind.

Dieser Beitrag spricht über die CLI VM statt der JVM, aber jeder ist in der Lage, ähnliche Dinge zu tun, so dass ich glaube, es ist relevant.

Ich bin Umgang mit diesem speziellen Problem in besonderer Weise für meine JIT. Beachten Sie, dass die Beschreibung hier konzeptuelle ist und die Code implementiert sie in eine etwas andere Art und Weise aus Leistungsgründen. Wenn ich eine Assembly laden, mache ich eine Notiz in dem Descriptor Methode, wenn es einfach ein Mitglied Feld zurückgibt. Als ich später andere Methoden JIT, ersetze ich alle call Anweisungen zu diesen Methoden in dem Byte-Code mit einer ldfld Anweisung, bevor es an den nativen Code-Generator vorbei. Auf diese Weise kann ich:

  1. Sparen Sie Zeit in der JIT (ldfld nimmt weniger Prozessorzeit JIT als call).
  2. Inline-Eigenschaften auch in der Baseline-Compiler .
  3. Im Großen und Ganzen gewährleistet, dass die öffentlichen Eigenschaften / private Felder Muster mit keinen Leistungseinbußen jeglicher Art entstehen, wenn der Debugger gelöst wird. (Wenn ein Debugger angeschlossen ist ich die Accessoren nicht inline kann.)

Ich habe keinen Zweifel, dass die großen Namen in der VM-Technologien sind bereits etwas ähnliches wie die Umsetzung (und wahrscheinlich besser als) diese in ihren Produkten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top