Objekttyp in schleife angeben oder außerhalb?

Status
Nicht offen für weitere Antworten.

-frank

Bekanntes Mitglied
ich wollte wissen, ob es in sachen performance einen unterschied gibt zwischen

Code:
Iterator<String> it = ...
...
while(it.hasNext()) {
    String str = it.next();
    ...
}

und:

Code:
Iterator<String> it = ...
...
{
    String str;
    while(it.hasNext()) {
        str = it.next();
        ...
    }
}

(der Block soll nur zeigen, dass "str" nachher nicht mehr gebraucht wird.)

ich wollte wissen, ob in der ersten Variante zur Laufzeit jedes mal ein neues String-Objekt erzeugt wird, dies dann natürlich Zeit benötigt, weiters alte Objekte erst vom Garbage Collector gelöscht werden müssen, etc.
...oder ob dies vom Compiler/Interpreter erkannt wird und beide Varianten gleichwertig sind.

ich frage nur, weil solche Iterationen einfach ständig vorkommen und ich mal wissen wollte, welche Variante eigentlich üblich ist bzw. besser.
 
String ist hier ein blödes Beispiel, denn Strings sind immutable und werden afaik immer neu erzeugt. Also ähnlich wie bei den primitiven Typen. Davon mal abgesehen würde ich Variante 1 immer bevorzugen. Man sollte das Scope einer Variablen immer so klein halten wie möglich. Desweiteren sollte man bedenken, dass Object o; nur eine Referenz erzeugt, also einen Zeiger darstellt. Erst das o = new Object(); erzeugt das eigentliche Objekt im Speicher. Du lagerst in Variante 2 nur die Definition der Referenz aus. Das verbessert die Performance nicht.
 
In diesem Beispiel werden überhaupt keine Objekte erzeugt :wink:

Und Strings verhalten sich wie ganz normale Objekte, nur wenn sie direkt im Code (ala String x = "bubu") stehen, werden sie besonders behandelt.
 
okay, vielleicht war das beispiel schlecht gewählt. (klar werden hier keine objekte neu erzeugt, sondern nur referenzen gesetzt).

wie wärs mit:

Code:
for(int i =0; i < MAX_I; i++) {
    SomeObject o = new SomeObject(i);
    ...
}

vs.

Code:
SomneObject o:
for(int i =0; i < MAX_I; i++) {
    o = new SomeObject(i);
    ...
}

in variante 2 ist der scope größer als notwendig. dafür wäre zumindest für einen menschen gleich ersichtlich, dass kein neuer speicher allokiert werden muss. aber bringt dies in java irgendwas? eh nicht, oder? also "new Object()" erzeugt sowieso ein neues Object und erst die Garbage Collection löscht das alte. (direkt das alte Objekt überschreiben und den zeiger nicht neu setzen kann java nicht (?))
also brirnt es nichts, oder?
 
"new" erzeugt ein neues Objekt - immer. Wie und ob der Compiler oder der JIT das noch abändert, oder ob das sowieso zum selben Code compiliert wird - kann ich dir nicht sagen.

Aber solche Mirkooptimierungen sind sowieso Zeitverschwendung... ein Schleifendurchgang weniger, und du hast alles wieder aufgeholt :wink:
 
Um Performance-Probleme sollte man sich kümmern, wenn man welche hat und die haben dann in der Regel mehr was mit miesen Algorithmen/Datenstrukturen zu tun.
Halte den Scope deiner Variablen so klein als möglich. Das macht den Code übersichtlicher, weil man nicht erst schauen muss, wo denn nun diese Variable wieder herkommt und gibt Ressourcen schneller für den Garbage Collector frei.
 
wäre es in meinem beispiel dann vermutlich am schnellsten, wenn ich auf "new SomeObject(i)" ganz verzichte (bzw. eben nur einmal ausführe) und dann ne methode wie reset(i) einführe, die ddas objekt neu initialisiert bzw. zurücksetzt. aber sowas wird man dann eben wirklich erst dann machen, wenn man die performance wirklich benötigt.

in meinem fall wollte ich wie gesagt nur mal wissen, wie man es generell macht. (also ich hab kein spezifisches problem, wo die performance ein problem wäre)

danke auf jeden fall!
 
So wie AlArenal geschrieben hat.

Die Anweisung

Code:
String s;

innerhalb eines Code-Blocks erzeugt ja schließlich keinen Laufzeitaufwand und
erhöht nur den Stackzeiger.
 
Das reinitialisieren eines Objekts wird in der Regel nicht weniger komplex sein, als das neu erstellen mit new... - es sei denn der Konfigurationsaufwand mit dem Konstruktor ist deutlich höher als eine reset-Methode... das ist aber wirklich im Einzelfall zu entscheiden, ob das ganze Sinn macht.
Die Verwendung eines Profilers macht Sinn, wenn man tatsächlich Performanceprobleme feststellt... damit kann man dann tatsächlich feststellen welche Methoden Geschwindigkeit ziehen... und in den seltensten Fällen wird es messbare Verbesserungen durch oben angesprochene Dinge geben...
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben