Der Umfang lokaler Variablen sollte immer so klein wie möglich sein.
In Ihrem Beispiel nehme ich an str
ist nicht außerhalb der verwendeten while
Schleife, sonst würden Sie nicht die Frage stellen, weil es in der Erklärung derwhile
der Schleife keine Option sein würde, da es nicht kompilieren würde.
Also, da str
ist nicht außerhalb der Schleife verwendet, der kleinste mögliche Spielraum für str
ist innerhalb der while - Schleife.
Die Antwort lautet also nachdrücklich, dass str
unbedingt innerhalb der while-Schleife deklariert werden sollte. Kein Wenn, kein Und, kein Aber.
Der einzige Fall, in dem diese Regel verletzt werden könnte, ist, wenn es aus irgendeinem Grund von entscheidender Bedeutung ist, dass jeder Taktzyklus aus dem Code herausgedrückt wird. In diesem Fall möchten Sie möglicherweise in Betracht ziehen, etwas in einem äußeren Bereich zu instanziieren und stattdessen wiederzuverwenden bei jeder Iteration eines inneren Bereichs erneut instanziieren. Dies gilt jedoch aufgrund der Unveränderlichkeit von Strings in Java nicht für Ihr Beispiel: Eine neue Instanz von str wird immer am Anfang Ihrer Schleife erstellt und muss am Ende weggeworfen werden gibt es dort keine optimierungsmöglichkeit.
EDIT: (fügt meinen Kommentar unten in die Antwort ein)
In jedem Fall besteht der richtige Weg darin, den gesamten Code richtig zu schreiben, eine Leistungsanforderung für Ihr Produkt festzulegen, Ihr Endprodukt an dieser Anforderung zu messen und die Dinge zu optimieren, wenn sie diese nicht erfüllen. Und was normalerweise passiert, ist, dass Sie an nur wenigen Stellen Möglichkeiten finden, einige nette und formale algorithmische Optimierungen bereitzustellen, die unser Programm dazu bringen, seine Leistungsanforderungen zu erfüllen, anstatt Ihre gesamte Codebasis zu durchlaufen und Dinge zu optimieren und zu hacken um hier und da Taktzyklen zu quetschen.
Ich habe den Bytecode dieser beiden (ähnlichen) Beispiele verglichen:
Schauen wir uns 1. Beispiel an :
nach
javac Test.java
,javap -c Test
bringen Sie:Schauen wir uns das 2. Beispiel an :
nach
javac Test.java
,javap -c Test
bringen Sie:Die Beobachtungen zeigen, dass es keinen Unterschied zwischen diesen beiden Beispielen gibt. Es ist das Ergebnis von JVM-Spezifikationen ...
Im Namen der besten Codierungspraxis wird jedoch empfohlen, die Variable im kleinstmöglichen Bereich zu deklarieren (in diesem Beispiel befindet sie sich innerhalb der Schleife, da dies der einzige Ort ist, an dem die Variable verwendet wird).
quelle
final
Liebhabern: erklären ,str
wiefinal
in deminside
Paket Fall auch keinen Unterschied macht =)Das Deklarieren von Objekten im kleinsten Bereich verbessert die Lesbarkeit .
Die Leistung spielt für die heutigen Compiler keine Rolle. (In diesem Szenario)
Aus Wartungssicht ist die zweite Option besser.
Deklarieren und initialisieren Sie Variablen an derselben Stelle im engstmöglichen Rahmen.
Wie Donald Ervin Knuth sagte:
dh) Situation, in der ein Programmierer Leistungsüberlegungen das Design eines Codeteils beeinflussen lässt. Dies kann in einem Entwurf zur Folge hat, dass ist nicht so sauber , wie es hätte sein können oder Code, der falsch ist, da der Code ist kompliziert durch die Optimierung und der Programmierer durch abgelenkt zu optimieren .
quelle
wenn Sie auch
str
außerhalb der Schleife verwenden möchten; erkläre es draußen. Ansonsten ist die 2. Version in Ordnung.quelle
Bitte springen Sie zur aktualisierten Antwort ...
Für diejenigen, die Wert auf Leistung legen, nehmen Sie das System.out heraus und begrenzen Sie die Schleife auf 1 Byte. Unter Verwendung von double (Test 1/2) und String (3/4) werden die verstrichenen Zeiten in Millisekunden mit Windows 7 Professional 64 Bit und JDK-1.7.0_21 angegeben. Bytecodes (auch unten für Test1 und Test2 angegeben) sind nicht identisch. Ich war zu faul, um mit veränderlichen und relativ komplexen Objekten zu testen.
doppelt
Test1 dauerte: 2710 ms
Test2 dauerte: 2790 ms
String (in den Tests einfach double durch string ersetzen)
Test3 dauerte: 1200 ms
Test4 dauerte: 3000 ms
Bytecode kompilieren und abrufen
AKTUALISIERTE ANTWORT
Es ist wirklich nicht einfach, die Leistung mit allen JVM-Optimierungen zu vergleichen. Es ist jedoch etwas möglich. Besserer Test und detaillierte Ergebnisse in Google Caliper
Teilprüfcode für doppelte Erklärung
Dies ist nicht identisch mit dem obigen Code. Wenn Sie nur eine Dummy-Schleife codieren, überspringt JVM diese, sodass Sie zumindest etwas zuweisen und zurückgeben müssen. Dies wird auch in der Caliper-Dokumentation empfohlen.
quelle
Eine Lösung für dieses Problem könnte darin bestehen, einen variablen Bereich bereitzustellen, der die while-Schleife einschließt:
Sie werden automatisch de-referenziert, wenn der äußere Bereich endet.
quelle
Je weniger Bereich die Variable im Inneren sichtbar ist, desto besser.
quelle
Wenn Sie die
str
After-the-while-Schleife (bereichsbezogen) nicht verwenden müssen, gilt die zweite Bedingung, d. H.ist besser, wenn Sie ein Objekt auf dem Stapel nur definieren, wenn das
condition
wahr ist. Ich benutze es, wenn du es brauchstquelle
Ich denke, die beste Ressource zur Beantwortung Ihrer Frage wäre der folgende Beitrag:
Unterschied zwischen der Deklaration von Variablen vor oder in der Schleife?
Nach meinem Verständnis wäre dieses Ding sprachabhängig. IIRC Java optimiert dies, sodass es keinen Unterschied gibt, aber JavaScript (zum Beispiel) übernimmt jedes Mal die gesamte Speicherzuweisung in der Schleife. Insbesondere in Java würde die zweite nach Abschluss der Profilerstellung schneller ausgeführt.
quelle
Wie viele Leute darauf hingewiesen haben,
ist NICHT besser als das:
Deklarieren Sie also keine Variablen außerhalb ihres Gültigkeitsbereichs, wenn Sie sie nicht wiederverwenden ...
quelle
Wenn Sie String str außerhalb der wile-Schleife deklarieren, kann innerhalb und außerhalb der while-Schleife auf ihn verwiesen werden. Wenn Sie String str innerhalb der while-Schleife deklarieren, kann nur innerhalb der while-Schleife darauf verwiesen werden.
quelle
Variablen sollten so nahe wie möglich an ihrem Verwendungsort deklariert werden.
Dies erleichtert RAII (Resource Acquisition Is Initialization) .
Es hält den Umfang der Variablen eng. Dadurch kann der Optimierer besser arbeiten.
quelle
Laut Google Android Development Guide sollte der variable Umfang begrenzt sein. Bitte überprüfen Sie diesen Link:
Variablenbereich begrenzen
quelle
Die
str
Variable wird verfügbar sein und auch nach der Ausführung unter dem Code etwas Speicherplatz reservieren.Die
str
Variable ist nicht verfügbar und es wird auch der Speicher freigegeben, derstr
im folgenden Code für die Variable zugewiesen wurde .Wenn wir dem zweiten folgen, wird dies sicherlich unseren Systemspeicher reduzieren und die Leistung steigern.
quelle
Das Deklarieren innerhalb der Schleife begrenzt den Umfang der jeweiligen Variablen. Es hängt alles von den Anforderungen des Projekts am Umfang der Variablen ab.
quelle
Die oben genannte Frage ist wirklich ein Programmierproblem. Wie möchten Sie Ihren Code programmieren? Wo muss auf die 'STR' zugegriffen werden? Es ist nicht sinnvoll, eine Variable zu deklarieren, die lokal als globale Variable verwendet wird. Grundlagen der Programmierung glaube ich.
quelle
Diese beiden Beispiele führen zu demselben Ergebnis. Mit der ersten Option können Sie die
str
Variable jedoch außerhalb der while-Schleife verwenden. der zweite ist nicht.quelle
Warnung für fast alle in dieser Frage: Hier ist ein Beispielcode, bei dem es innerhalb der Schleife auf meinem Computer mit Java 7 leicht 200-mal langsamer sein kann (und der Speicherverbrauch ist auch etwas anders). Es geht aber um Allokation und nicht nur um Umfang.
Schlussfolgerung: Abhängig von der Größe der lokalen Variablen kann der Unterschied selbst bei nicht so großen Variablen sehr groß sein.
Nur um zu sagen, dass manchmal außerhalb oder innerhalb der Schleife eine Rolle spielt.
quelle
bigStuff[(int) (value % STUFF_SIZE)] = value;
(versuchen Sie einen Wert von 2147483649L)Ich denke, die Größe des Objekts ist ebenfalls wichtig. In einem meiner Projekte hatten wir ein großes zweidimensionales Array deklariert und initialisiert, wodurch die Anwendung eine Ausnahme wegen Speichermangels auslöste. Wir haben stattdessen die Deklaration aus der Schleife verschoben und das Array zu Beginn jeder Iteration gelöscht.
quelle
Sie haben das Risiko,
NullPointerException
dass IhrecalculateStr()
Methode null zurückgibt und Sie dann versuchen, eine Methode für str aufzurufen.Vermeiden Sie generell Variablen mit einem Nullwert . Es ist übrigens stärker für Klassenattribute.
quelle
NullPointerException.
Falls dieser Code versucht ,return str;
es würde ein Übersetzungsfehler auftreten.