An welchem Punkt hört die Verwendung eines StringBuilder bedeutungslos geworden oder ein overhead?

StackOverflow https://stackoverflow.com/questions/550702

  •  23-08-2019
  •  | 
  •  

Frage

Kürzlich habe ich mich mit StringBuilder für alle string-Verkettungen, groß und klein, jedoch in einer aktuellen performance-test habe ich ausgelagert einer Kollegin stringOut = string1 + "." string2 Stil Verkettung (in einer 10000x + Schleife mit dem StringBuilder-Objekt wird newed jedes mal) für einen StringBuilder, nur um zu sehen, welchen Unterschied es machen würde, in a minor Verkettung.

Ich fand, die sich über viele Auflagen von der performance-test, die änderung wurde sowohl unwesentlich höher oder niedriger, unabhängig von der Verkettung oder StringBuilder (wiederholte dies war für kleine Verkettungen).

An welchem Punkt hört die 'newing' der ein StringBuilder-Objekt zu negieren die Vorteile der Verwendung?

War es hilfreich?

Lösung

Die Regel, der ich Folge, ist -

Verwenden Sie einen StringBuilder, wenn die Anzahl der Verkettungen ist unbekannt, zur compile-Zeit.

Also, in Ihrem Fall jede StringBuilder war nur Anhängen ein paar mal und dann verworfen.Das ist nicht wirklich das gleiche als so etwas wie

string s = String.Empty;
for (int i = 0; i < 10000; ++i)
{
    s += "A";
}

Dort, wo die Verwendung eines StringBuilder würde drastisch die Leistung verbessern, da Sie sonst ständig der Zuweisung von neuen Speicher.

Andere Tipps

Ich bin sicher, ich habe eine andere Antwort, wo ich gebucht, nur link zu meinem Artikel und dann die Zusammenfassung, aber hier gehen wir wieder.

  • Auf jeden Fall nutzen StringBuilder wenn Sie sind verkettet in einer nicht-trivialen Schleife - vor allem, wenn Sie nicht wissen, für sicher (zur compile-Zeit) wie viele Iterationen machen Sie durch die Schlaufe.Zum Beispiel liest eine Datei ein Zeichen in einer Zeit, Aufbau einer Zeichenfolge, wie Sie gehen mit dem + = - operator ist möglicherweise von performance-Selbstmord.

  • Definitiv verwenden Sie den operator, wenn man (gut lesbar) geben Sie alles, was Bedürfnisse zu werden verkettet in einer Erklärung.(Wenn Sie haben eine Reihe von Dingen zu verketten, sollten den Aufruf String.Concat explizit - oder String.Join wenn Sie ein Trennzeichen.)

  • Haben Sie keine Angst zu brechen, Literale werden in mehrere verkettete bits - das Ergebnis wird das gleiche sein.Sie können Hilfe Lesbarkeit durch den Bruch eines langen literal in mehrere Linien, zum Beispiel, mit keine Schaden, um die Leistung.

  • Wenn Sie die Zwischenergebnisse der Verkettung für etwas anderes als Zuführung der nächsten iteration der Verkettung, StringBuilder ist nicht gehen zu helfen Sie.Zum Beispiel, wenn Sie, erstellen Sie einen vollständigen Namen aus einem Vornamen und einen Nachnamen ein, und fügen Sie dann eine Dritte information (der Spitzname, vielleicht) zu Ende, Sie werden nur von nutzen sein StringBuilder wenn Sie brauchen nicht die (erste name + letzten name) - Zeichenfolge für andere Zwecke (wie wir in dem Beispiel, wodurch eine Person Objekt).

  • Wenn Sie nur ein paar Verkettungen zu tun, und Sie wirklich wollen, um Sie zu tun im separaten Anweisungen ist es nicht eigentlich egal, welchen Weg Sie gehen.Welcher Weg effizienter ist, hängt von der Anzahl der Verkettungen die Größen von string einbezogen werden und in welcher Reihenfolge Sie sind verkettet in.Wenn Sie wirklich glauben, dass Stück von code zu einem performance-Engpass -, Profil-oder benchmark es in beide Richtungen.

Manchmal ist es lohnt ein Blick auf die Dokumentation:

Die Leistung einer Verkettung Betrieb für eine Zeichenfolge oder StringBuilder-Objekt hängt davon ab, wie oft eine Speicherzuweisung erfolgt.Ein String-Verkettung Betrieb immer Speicher zuweist, während eine StringBuilder verkettungsoperation nur Speicher reserviert, wenn die StringBuilder-Objekt Puffer zu klein, um die neuen Daten aufzunehmen.Folglich ist die String-Klasse bevorzugt für die Verkettung Betrieb, wenn eine Feste Anzahl von String Objekte verkettet.In diesem Fall, die individuelle Verkettung Operationen könnten auch kombiniert werden eine einzige Bedienung durch den compiler.Ein StringBuilder-Objekt wird bevorzugt für eine Verkettung Betrieb, wenn eine beliebige Anzahl von strings verkettet;zum Beispiel, wenn eine Schleife verkettet eine zufällige Reihe von strings of user input.

In Ihrem Beispiel gibt es nur eine einzige Verkettung pro Ausgabe-string, so StringBuilder erhält Sie nichts.Sie sollte verwenden Sie StringBuilder in Fällen, in denen Sie hinzufügen, um die dieselbe Zeichenfolge viele Male, z.B.:

stringOut = ...
for(...)
    stringOut += "."
    stringOut += string2

Meine Faustregel ist einfach.

  1. Wenn man einigermaßen schreiben kann ein einzelner Ausdruck, produziert der Letzte, dann verwenden +.
  2. Wenn Sie können nicht (entweder durch Größe oder Variabilität), dann verwenden Sie StringBuilder.

In meiner Erfahrung, Ausdrücke wie:

"Id: " + item.id + " name: " + item.name

geschrieben werden kann und verstanden, viel leicht als:

StringBuilder sb = new StringBuilder();
sb.append("Id: ").append(item.id);
sb.append(" name: ").append(item.name);

(gefolgt von mit dem string von sb wo die obigen Ausdruck wäre geschrieben worden), und es funktioniert genauso gut (Tipp:Blick auf den kompilierten code, um zu sehen, warum!)

Auf der anderen Seite, wenn Sie sammeln müssen, um eine Zeichenfolge im Laufe der Zeit (so wie das Programm ausgeführt wird) oder Raum (aus-Werte aus unterschiedlichen teilen des Codes), so dass es unpraktisch ist, zu schreiben, als einen einzeiligen Ausdruck, dann StringBuilder vermeidet den Aufwand (Zeit und Speicher-Buttern) von:

String s = somethingExpression;
...
s += someOtherExpression;
...
s += yetAnotherExpression;
...

Von MSDN:

[T]er String-Klasse ist besser für eine Verkettung operation, wenn eine Feste Anzahl der String-Objekte sind verkettet.In diesem Fall, die individuelle Verkettung von Operationen vielleicht auch zu einem vereint werden Bedienung durch den compiler.Ein StringBuilder-Objekt wird bevorzugt für eine Verkettung Betrieb, wenn eine beliebige Anzahl von strings verkettet;zum Beispiel, wenn eine Schleife verkettet eine zufällige Reihe von strings of user input.

Ich denke, die Antwort ist "es hängt" - wenn Sie sind verkettet in einer Schleife mit mehr als einer Handvoll von Iterationen dann ein StringBuilder-Objekt wird fast immer eine bessere performance liefern, aber der einzige Weg, um sicher wissen, ist tatsächlich Profil.

Es gibt einen interessanten Artikel über an Coding Horror.Jeff bekam die folgenden Ergebnisse für 100.000 Iterationen auf einem dual-core 3.5 GHz Core 2 Duo:

 Simple Concatenation    - 606 ms
 String.Format           - 665 ms
 string.Concat           - 587 ms
 String.Replace          - 979 ms
 StringBuilder           - 588 ms

Von Dot Net Perls:

Wann verwenden Sie StringBuilder?

StringBuilder ist einzig und allein eine Optimierung, und es bietet keine logische Verbesserungen string Concat anderen als seiner internen Umsetzung.Das heißt, es ist wichtig es richtig zu verwenden, die in Ihrem high-performance-Anwendungen und web-Seiten.

Manchmal, es ist in Ordnung mit kleinen Schleifen von 4 oder weniger Iterationen mit einfachen string Concats.Jedoch, im Rand Fällen kann dies verheerend sein.Planen Sie Ihre edge-Fällen, die mit StringBuilder.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top