Die Schleife hat eine bessere Leistung? Warum?
String s = "";
for(i=0;i<....){
s = some Assignment;
}
oder
for(i=0;i<..){
String s = some Assignment;
}
Ich brauche nicht zu verwenden, " s " außerhalb der Schleife immer und immer wieder.
Die erste option ist vielleicht auch besser, da ein neues String ist nicht initialisiert jedes mal. Die zweite jedoch in den Bereich der Variablen begrenzt auf die Schleife selbst.
EDIT: In Reaktion auf Milhous Antwort. Es wäre sinnlos, weisen Sie die Zeichenfolge, um eine Konstante innerhalb einer Schleife wäre es nicht? Nein, hier 'einige Abtretung" bedeutet einen Wechsel Wert wurde aus der Liste Durchlaufen.
Auch, die Frage ist nicht, weil ich bin besorgt über memory-management. Möchte nur wissen, was besser ist.
- Es ist nicht ungewöhnlich, um zu iterieren über eine collection von strings angegeben als Literale. Zum Beispiel werden die Spaltenüberschriften einer Tabelle kann hart codiert als String[]. Was ist wichtig, obwohl, ist, dass die gleiche Zuordnung geschieht in beiden Fällen, und so ist es nicht beeinflussen die Antwort.
- Ein weiterer Kommentar: vergessen Sie nicht, dass wenn du nicht gehst, um den Wert zu ändern von
s
sollten Sie erklären esfinal
. Viele Java-Programmierer vergessen, dass all zu oft.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Begrenztem Umfang ist die Beste
Verwenden Sie die zweite option:
Umfang nicht auf die Leistung Auswirken
Wenn Sie das disassemblieren von code ist der kompilierte von jedem (mit dem JDK ist
javap
tool), sieht man, dass die Schleife kompiliert, die genau die gleiche JVM-Instruktionen in beiden Fällen. Beachten Sie auch, dass Brian R. Bondy ' s "Option #3" ist identisch zu Option #1. Nichts extra Hinzugefügt wird oder vom stack entfernt, wenn über den engeren Rahmen und die gleichen Daten verwendet werden, auf dem stack in beiden Fällen.Vermeiden Vorzeitigen Initialisierung
Der einzige Unterschied zwischen den beiden Fällen ist, dass im ersten Beispiel die variable
s
ist unnötig initialisiert. Dies ist ein weiteres Problem aus der Position der Variablen-Deklaration. Dies fügt zwei verschwendet Anweisungen (zum laden eine string-Konstante, und speichern Sie es in einen stack-frame, slot). Ein gutes tool für die statische Analyse wird Sie warnen, dass Sie nie Lesen den Wert, den Sie zuweisens
, und ein guter JIT-compiler wird wahrscheinlich umgehen, aber zur Laufzeit.Könnten Sie dieses Problem beheben, indem einfach eine leere Deklaration (d.h.,
String s;
), aber dies wird als schlechte Praxis und hat einen weiteren Nebeneffekt, die unten besprochen.Oft einen falschen Wert wie
null
einer Variablen zugewiesen ist, einfach zu hush zu einem compiler-Fehler, dass eine variable gelesen wird, ohne dass Sie initialisiert wurde. Dieser Fehler kann als ein Hinweis, dass der Geltungsbereich von Variablen ist zu groß, und es wird erklärt, bevor es ist notwendig, um einen gültigen Wert. Leere Deklarationen zwingen Sie zu denken, jedes code-Pfad; ignorieren Sie nicht diese wertvolle Warnung durch die Zuordnung einen falschen Wert.Sparen Stack-Slots
Wie erwähnt, während die JVM-Instruktionen sind die gleichen in beiden Fällen, es ist die subtile Seite-Effekt, der macht es am besten, an einem JVM-Ebene, verwenden die meisten beschränkten Umfang möglich. Sichtbar wird dies in der "local-variable-Tabelle" für die Methode. Überlegen Sie, was passiert, wenn Sie mehrere Schleifen, mit den Variablen, die in unnötig großer Umfang:
Den Variablen
s
undn
deklariert werden könnte, innerhalb Ihrer jeweiligen loops, aber da Sie nicht sind, verwendet der compiler zwei "slots" in den stack-frame. Wenn Sie waren innerhalb der Schleife deklariert, kann der compiler die Wiederverwendung der gleichen Steckplatz, so dass der stack-frame kleiner., Was Wirklich Zählt
Jedoch, die meisten dieser Probleme sind unwesentlich. Ein guter JIT-compiler werden sehen, es ist nicht möglich, Lesen Sie den ersten Wert, den Sie verschwenderisch zuweisen, und optimieren Sie die Zuweisung entfernt. Spart einen Steckplatz, die hier oder dort nicht gehen, um Pause machen oder Ihre Bewerbung.
Die wichtige Sache ist, um Ihren code lesbar und leicht zu pflegen, und in dieser Hinsicht mit begrenztem Umfang ist deutlich besser. Die kleineren Geltungsbereich einer variable ist, desto leichter ist es zu verstehen, wie es verwendet wird, und welche Auswirkungen änderungen am code vorgenommen haben.
String
bei jeder iteration der Schleife, und Sie Fragen sich, ob diese Berechnung können Sie "hochgezogen", ja, es ist möglich, aber es hängt von der JVM.""
zus
im ersten Beispiel in der original-post? Der Wert, der nie Lesen, bevor Sie überschrieben wird bei der ersten iteration der Schleife? Das ist, was ich Rede in dem Abschnitt "Vermeiden Sie die Vorzeitige Initialisierung"; dieldc
undastore
Anweisungen verschwendet werden, weil dieser Wert kann nie gelesen werden, bevor die variable zugewiesen. Der code inside die Schleife ist die gleiche. Die Initialisierung (Belegung) der Variablen ist ein eigenes Thema aus dem Bereich der Variablen.In Theorie, es ist eine Verschwendung von Ressourcen zu deklarieren die Zeichenfolge innerhalb der Schleife.
In Praxis, aber die snippets, die Sie präsentiert wird kompilieren bis hin zu den gleichen code (Deklaration außerhalb der Schleife).
So, wenn dein compiler hat jede Menge Optimierung, da gibt es keinen Unterschied.
Im Allgemeinen würde ich wählen Sie die zweite, weil der Umfang der " s " - Variablen ist beschränkt auf die Schleife. Vorteile:
Wenn Sie möchten, um die Geschwindigkeit for-Schleifen, ich bevorzuge die Deklaration einer variable max neben der Theke, so dass keine wiederholte Suchvorgänge für die condidtion sind erforderlich:
statt
Ich lieber
Alle anderen Dinge, die Sie berücksichtigen sollten, ist bereits gesagt worden, also nur meine zwei Cent (siehe ericksons post)
Greetz, GHad
Hinzufügen ein bisschen zu @Esteban Araya Antwort, Sie werden beide erfordern die Schaffung einer neuen Zeichenfolge jedes mal durch die Schleife (als Rückgabewert der
some Assignment
Ausdruck). Diese Zeichenfolgen werden müssen, die garbage Collection so oder so.Ich weiß, das ist eine alte Frage, aber ich dachte, ich fügen Sie ein wenig, dass leicht Verwandte.
Habe ich bemerkt, während das surfen im Java-source-code, einige Methoden, wie String.contentEquals (ebenfalls unten) macht redundante lokale Variablen sind lediglich Kopien der Klassenvariablen. Ich glaube, dass ein Kommentar irgendwo, dass impliziert, dass der Zugriff auf lokale Variablen schneller ist als der Zugriff auf Klassenvariablen.
In diesem Fall "v1" und "v2" sind scheinbar überflüssig und könnte abgeschafft werden, um den code vereinfachen, wurden aber Hinzugefügt, um die Leistung zu verbessern.
Scheint es mir, dass wir mehr brauchen Spezifikation des Problems.
Den
ist nicht angegeben, um welche Art von Zuordnung es ist. Wenn die Zuweisung
dann ein neues stechen muss zugeordnet werden.
aber wenn es
s nur um den Konstanten-Speicher, und damit die erste version wäre mehr Speicher effizient.
Scheint, ich etwas albern, sich sorgen über zu viel Optimierung einer for-Schleife für eine interpretierte lang IMHO.
Wenn ich mit mehreren threads (50+) dann habe ich festgestellt, dass dies ein sehr effektiver Weg, der Umgang mit ghost-thread Probleme mit nicht in der Lage, zu schließen, einen Prozess richtig ....wenn ich falsch bin, bitte lassen Sie mich wissen, warum ich falsch Liege: