2010-08-02 12 views
11

Ist:Deklariert eine Variable innerhalb/außerhalb einer Schleife die Leistung? diese

foreach(Type item in myCollection) 
{ 
    StringBuilder sb = new StringBuilder(); 
} 

viel langsamer als:

StringBuilder sb = new StringBuilder(); 

foreach(Type item in myCollection) 
{ 
    sb = new StringBuilder(); 
} 

Mit anderen Worten, wird es wirklich wichtig, wo ich meine StringBuilder erklären?

+3

Ähnlich wie http://stackoverflow.com/questions/2447475/best-practice-for-creating-objects-used-in-for-foreach-loops –

+1

Ein nicht verwandter Fehler ist, dass die zweite Version auf Null initialisiert werden sollte um eine Überzuteilung zu vermeiden. –

Antwort

12

könnten Sie vielleicht einige Performance gewinnen, wenn Sie diesen schreiben:

StringBuilder sb = new StringBuilder(); 
foreach(Type item in myCollection) 
{ 
    sb.Length = 0; 
} 

So müssen Sie nur einmal die String instanziiert und die Größe in der Schleife zurückzusetzen, die ein neues Objekt als Instanziieren etwas schneller sein sollte .

+0

+1 guter Punkt ... – SLaks

+1

+1: Abhängig von der Größe der eingebauten Zeichenfolge und dem resultierenden internen Puffer in sb könnte dies einen messbaren Unterschied machen. – Alex

+2

Es könnte, aber es könnte auch nicht. Wenn Sie 'ToString' aufrufen, wird der Puffer kopiert. Ich würde es Benchmarks unterstellen, vorausgesetzt, es gab einen Grund zu der Annahme, dass es leistungsabhängig ist. –

14

Nein, die Leistung spielt keine Rolle, wenn Sie es deklarieren.

Für allgemeine Code-Sauberkeit, sollten Sie es im innersten Umfang deklarieren, dass es verwendet wird - dh. dein erstes Beispiel.

+1

Dies sollte in die gleiche IL sowieso kompilieren, denke ich.Nun, es wäre, wenn er nicht zweimal jdm initialisieren würde. –

+1

Korrigieren Sie mich, wenn ich falsch liege, aber wenn Sie es innerhalb der Schleife deklarieren, wird es nicht außerhalb davon unbenutzbar (nicht deklariert) machen? – NullUserException

+3

@NullUserException Ja, Sie haben Recht. Aber wenn Sie es außerhalb der Schleife nicht brauchen, ist es klarer, es innerhalb der Schleife zu erklären – sloth

2

Im zweiten Beispiel erstellen Sie eine zusätzliche Instanz von StringBuilder. Abgesehen davon, dass sie beide gleich sind, ist das Leistungsproblem vernachlässigbar.

+0

Dies sollte ein Kommentar zu der Frage meiner Meinung nach sein. – Shaihi

+0

@Shaihi - Warum? w69rdy gibt eine Antwort auf die Frage. – mphair

1

Hier ist nicht genügend Code vorhanden, um einen Leistungsunterschied in Ihrem speziellen Fall deutlich anzuzeigen. Abgesehen davon ist der Unterschied zwischen der Deklaration einer Referenzvariablen innerhalb einer Schleife wie dieser gegenüber der Außenseite für die meisten Fälle trivial.

1

Der effektive Unterschied zwischen Ihren beiden Codebeispielen besteht darin, dass die zweite 1 weitere Instanz StringBuilder als die erste zuweist. Der Leistungseinfluss im Vergleich zum Rest Ihrer Anwendung ist im Wesentlichen nichts.

0

Der beste Weg zu überprüfen ist, indem Sie beide Methoden in einer Schleife, etwa 100.000 pro. Messen Sie die Zeit, die jede 100.000 Iterationen benötigen, und vergleichen Sie sie. Ich denke nicht, dass es einen großen Unterschied gibt. Aber es gibt einen kleinen Unterschied. Das erste Beispiel enthält so viele Variablen wie die Anzahl der Iterationen. Das zweite Beispiel hat nur eine Variable. Der Compiler ist schlau genug, hier einige Optimierungen vorzunehmen, damit Sie keine Geschwindigkeitsverbesserung bemerken. Wenn Sie jedoch nicht das letzte in der Schleife generierte Objekt verwenden möchten, wenn Sie sich erneut außerhalb der Schleife befinden, wäre die erste Lösung besser. In der zweiten Lösung dauert es nur eine Weile, bis der Garbage Collector das letzte erstellte Objekt freigibt. Im ersten Beispiel wird der Garbage Collector beim Freigeben des Objekts etwas schneller sein. Es hängt vom Rest des Codes ab, aber wenn Sie viele Daten in diesem StringBuilder-Objekt speichern, kann das zweite Beispiel diesen Speicher viel länger halten, wodurch die Leistung Ihres Codes nach Verlassen der Schleife sinkt!
Dann wieder, wenn die Objekte 100 KB auffressen und Sie 16 GB in Ihrer Maschine haben, kümmert sich niemand ... Der Müllsammler wird es schließlich wieder freigeben, wahrscheinlich sobald Sie die Methode verlassen, die diese Schleife enthält.

0

Wenn Sie andere Codesegmente des gleichen Typs haben, können Sie den Code immer mit Profilen oder Zeitgebern versehen und einen Benchmark-Test durchführen, um selbst zu sehen. Ein weiterer Faktor wäre der Memory Footprint, zu dem sich andere geäußert haben.

Verwandte Themen