Variable vs. return value

Ok, sorry für den Titel der ist vielleicht etwas unpassend! Ich versuche mal darzustellen was ich mich gefragt hatte:

Was ist besser(performanter):

erstmal Klasse1:

Object obj = new Object();
public Object getObject() {
     return obj;
}

Und hier die verschiedenen Methoden:

public void test() {
     while (true) {
          klasse1Instanz.getObject().doSomething;
     }
}

ODER

public void test() {
     Object objVar = klasse1Instanz.getObject();
     while (true) {
          objVar.doSomething;
     }
}

Was ist nun schneller? Und was zeugt von besserem Stil?
Stört euch nicht an dem while(true) nur zum verdeutlichen!

Da getter und setter starke Kandidaten für inlining sind, behaupte ich mal das ist völlig egal.
Orientiere dich lieber daran, was lesbarer ist :slight_smile:

Performance auf dem Level zu optimieren hat allgemein wenig Sinn. Beim Ausführen und Compilen passiert soviel im Hintergrund, dass man da nur schwer gezielt anpassen kann.
Lieber die Codekomplexität verringern (bessere Algorythmen) oder gezielt langsame Stellen suchen und die anpassen (Profiling).

Gruß

SCOPE !
es kommt drauf an ob du das was von einer methode returnt wird auch nur direkt an dieser einen stelle brauchst oder innerhalb des blocks mehrfach darauf zugreifen musst

brauchst du z.b. den wert einer berechnung nur einmal um halt in einem if diesen zu prüfen würde man direkt den getter nutzen
brauchst du das ergebnis aber mehrfach in einem block solltest du eine variable nehmen, vor allem dann wenn die rechnung sehr komplex ist und neben-effekte wie z.b. inkrement enthält und somit bei mehrfachem call andere ergebnisse rauskommen

Nur noch mal zusammengefasst
wenn du das Object in deiner while nur einma brauchst dann so.

  while (true) {
    klasse1Instanz.getObject().doSomething;
  }
}```
Wenn du aber mehrere Methode darauf anwenden möchtest, dann so

public void test() {
Object objVar = klasse1Instanz.getObject();
while (true) {
objVar.doSomething;
objVar.doSomethingOther;
objVar.doSomething2;
}
}```
damit ist direkt erkennbar, dass du immer nur auf dem selben Object arbeitest.
Natürlich könnte auch je nach Anwendungsfall die ZeileObject objVar = klasse1Instanz.getObject(); als erster Befehel innerhalb der while-Schleife stehen.

der Anwendungsfall ist recht simpel → wird objVar noch nach der while Schleife gebraucht ? oder nur innen ?

wie schon gesagt wurde, scope immer klein halten

Wenn du weißt, wie “getObject” implementiert ist, kann es egal sein. Aber wenn man es nicht weiß, und das irgendwie performancekritisch ist, sollte man die Variante verwenden, bei der man sich das Objekt VOR der Schleife holt.

public Object getObject()
{
    long ätsch = 1000000;
    try { Thread.sleep(ätsch); } catch (...) { ...}
    return null;
}

Wenn man in einem Projekt arbeitet wo sowas noch als „getter“ verkauft wird, ist es auch egal ob man Variablen vor- oder in der Schleife deklariert :slight_smile:

Gruß

Liefert getObject immer das selbe?

Was wenn nicht?

Auch in Zukunft?

Auch im Kontext einer Multi-Threaded-Anwendung?

Eigentlich würde ich da zustimmen - aber zusätzlich zu Majoras äußerst validen Einwänden: Wenn eine Methode mit „get“ anfängt, finde ich dass dort eigentlich nichts berechnet werden sollte. Doch unabhängig von der Frage, ob man seine Methoden dann immer „obtainXXX“, „findXXX“, „computeXXX“ oder sonstwie nennen sollte, muss man davon ausgehen, dass sich sowas ändern kann, und man (klar: bei einer „öffentlichen API“) die Methode eben nicht einfach rausnehmen kann, auch WENN sie „getXXX“ heißt und in einer neueren Version dort dann DOCH etwas berechnet wird.

Guter Stil wäre es sich den Getter komplett zu sparen und stattdessen die Methode klasse1Instanz.doSomething() einzuführen (-> Demeters Gesetz).
Wegen der Performance - probier halt alle Möglilchkeiten aus und schau nach ob eine davon auffallend schneller ist als die anderen. Oder, noch besser, schau dir die Ausgabe von java -XX:+UnlockDiagnosticVMOptions '-XX:CompileCommand=print,*MyClass.test' MyClass an und versuch daraus schlau zu werden…