Ja, der Leistungsunterschied ist erheblich. Weitere Informationen finden Sie im KB-Artikel " Verbessern der Verkettungsleistung von Zeichenfolgen in Visual C # ".
Ich habe immer versucht, zuerst aus Gründen der Klarheit zu codieren und später die Leistung zu optimieren. Das ist viel einfacher als umgekehrt! Nachdem ich jedoch den enormen Leistungsunterschied in meinen Anwendungen zwischen den beiden gesehen habe, denke ich jetzt etwas genauer darüber nach.
Glücklicherweise ist es relativ einfach, eine Leistungsanalyse für Ihren Code durchzuführen, um festzustellen, wo Sie die Zeit verbringen, und ihn dann so zu ändern, dass er StringBuilder
bei Bedarf verwendet werden kann.
Um zu verdeutlichen, was Gillian über 4 Saiten gesagt hat, wenn Sie so etwas haben:
dann wäre es schneller mit Strings und dem Plus-Operator. Dies liegt daran, dass (wie Java, wie Eric betont) intern StringBuilder automatisch verwendet wird (tatsächlich wird ein Grundelement verwendet, das auch StringBuilder verwendet).
Wenn das, was Sie tun, jedoch näher liegt an:
Dann müssen Sie explizit einen StringBuilder verwenden. .Net erstellt hier nicht automatisch einen StringBuilder, da dies sinnlos wäre. Am Ende jeder Zeile muss "a" eine (unveränderliche) Zeichenfolge sein, sodass in jeder Zeile ein StringBuilder erstellt und entsorgt werden muss. Aus Gründen der Geschwindigkeit müssen Sie denselben StringBuilder verwenden, bis Sie mit dem Erstellen fertig sind:
quelle
a
es sich um eine lokale Variable handelt und das Objekt, auf das verwiesen wird, keiner anderen Variablen zugewiesen wurde (auf die möglicherweise ein anderer Thread zugreifen kann), kann ein guter Optimierer feststellen, dass während dieser Sequenz von keinem anderen Codea
zugegriffen wird Linien; nur der endgültige Wert dera
Dinge. So könnten diese drei Codezeilen so behandelt werden, als wären sie geschriebena = b + c + d;
.Stringbuilder ist bevorzugt IF Sie mehrere Schleifen tun, oder Gabeln in Ihrem Code Pass ... aber für PURE Leistung, wenn Sie mit einem wegkommen kann SINGLE String Erklärung, dann die viel mehr performant ist.
Beispielsweise:
ist performanter als
In diesem Fall kann StringBuild als wartbarer angesehen werden, ist jedoch nicht leistungsfähiger als die Deklaration einzelner Zeichenfolgen.
9 mal von 10 ... benutze den String Builder.
Nebenbei bemerkt: string + var ist auch leistungsfähiger als der string.Format-Ansatz (im Allgemeinen), der intern einen StringBuilder verwendet (im Zweifelsfall ... Reflektor prüfen!)
quelle
Ein einfaches Beispiel, um den Geschwindigkeitsunterschied bei der Verwendung von
String
Verkettung zu demonstrierenStringBuilder
:Ergebnis:
Ergebnis:
Infolgedessen dauerte die erste Iteration 15423 ms, während die zweite Iteration mit
StringBuilder
10 ms dauerte.Es scheint mir, dass die Verwendung
StringBuilder
schneller ist, viel schneller.quelle
Dieser Benchmark zeigt, dass die regelmäßige Verkettung schneller ist, wenn 3 oder weniger Zeichenfolgen kombiniert werden.
http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/
StringBuilder kann die Speichernutzung erheblich verbessern, insbesondere wenn Sie 500 Zeichenfolgen addieren.
Betrachten Sie das folgende Beispiel:
Was passiert im Gedächtnis? Die folgenden Zeichenfolgen werden erstellt:
Durch Hinzufügen dieser fünf Zahlen am Ende der Zeichenfolge haben wir 13 Zeichenfolgenobjekte erstellt! Und 12 von ihnen waren nutzlos! Beeindruckend!
StringBuilder behebt dieses Problem. Es ist keine "veränderbare Zeichenfolge", wie wir oft hören ( alle Zeichenfolgen in .NET sind unveränderlich ). Es funktioniert, indem ein interner Puffer, ein Array von Zeichen, beibehalten wird. Durch Aufrufen von Append () oder AppendLine () wird die Zeichenfolge dem leeren Bereich am Ende des char-Arrays hinzugefügt. Wenn das Array zu klein ist, wird ein neues, größeres Array erstellt und der Puffer dort kopiert. Im obigen Beispiel benötigt StringBuilder möglicherweise nur ein einziges Array, um alle 5 Ergänzungen zum String zu enthalten - abhängig von der Größe seines Puffers. Sie können StringBuilder mitteilen, wie groß der Puffer im Konstruktor sein soll.
quelle
i.ToString()
. Mit StringBuilder müssen Sie also noch 6 + 1 Zeichenfolgen erstellen. Das Erstellen von 13 Zeichenfolgen wurde auf 7 Zeichenfolgen reduziert. Aber das ist immer noch die falsche Sichtweise; Die Erstellung der sechs Zahlenfolgen ist nicht relevant. Fazit: Sie hätten die sechs Zeichenfolgen von einfach nicht erwähnen solleni.ToString()
. Sie sind nicht Teil des Effizienzvergleichs.Ja,
StringBuilder
bietet eine bessere Leistung bei wiederholter Operation über eine Zeichenfolge. Dies liegt daran, dass alle Änderungen an einer einzelnen Instanz vorgenommen werden, sodass viel Zeit gespart werden kann, anstatt eine neue Instanz wie zu erstellenString
.String gegen Stringbuilder
String
System
NamespaceStringBuilder
(veränderbare Zeichenfolge)System.Text
Namespacequelle
String Vs String Builder:
Als erstes muss man wissen, in welcher Versammlung diese beiden Klassen leben?
So,
Zeichenfolge ist im
System
Namespace vorhanden.und
StringBuilder ist im
System.Text
Namespace vorhanden.Für die Zeichenfolgendeklaration :
Sie müssen den
System
Namespace einschließen . etwas wie das.Using System;
und
Für die StringBuilder- Deklaration:
Sie müssen den
System.text
Namespace einschließen . etwas wie das.Using System.text;
Nun kommt die eigentliche Frage.
Was ist der Unterschied zwischen string & StringBuilder ?
Der Hauptunterschied zwischen diesen beiden ist:
Zeichenfolge ist unveränderlich.
und
StringBuilder ist veränderbar.
Lassen Sie uns nun den Unterschied zwischen unveränderlich und veränderlich diskutieren
Veränderliche: : Mittel veränderbare.
Unveränderliche: : Mittel nicht veränderbarer.
Beispielsweise:
In diesem Fall werden wir also dasselbe Objekt fünfmal ändern.
Die offensichtliche Frage ist also: Was passiert eigentlich unter der Haube, wenn wir die gleiche Saite fünfmal wechseln?
Dies passiert, wenn wir dieselbe Zeichenfolge fünfmal ändern.
Schauen wir uns die Figur an.
Erklärung:
Wenn wir diese Variable "name" zum ersten Mal auf "Rehan" initialisieren, dh
string name = "Rehan"
diese Variable wird auf dem Stapel "name" erstellt und zeigt auf diesen "Rehan" -Wert. Nachdem diese Zeile ausgeführt wurde: "name = name +" Shah ". Die Referenzvariable zeigt nicht mehr auf das Objekt" Rehan ", sondern auf" Shah "und so weiter.So
string
ist unveränderlich Bedeutung , dass , wenn wir das Objekt im Speicher erstellen können wir nicht ändern.Wenn wir also die
name
Variable zusammenfassen, bleibt das vorherige Objekt im Speicher und es wird ein weiteres neues Zeichenfolgenobjekt erstellt ...Aus der obigen Abbildung haben wir also fünf Objekte, die vier Objekte werden weggeworfen, sie werden überhaupt nicht verwendet. Sie bleiben immer noch im Gedächtnis und nehmen die Menge des Gedächtnisses ein. "Garbage Collector" ist dafür verantwortlich, dass die Ressourcen aus dem Speicher entfernt werden.
Im Falle einer Zeichenfolge haben wir also immer dann, wenn wir die Zeichenfolge immer wieder manipulieren, einige viele Objekte erstellt und bleiben dort im Speicher.
Das ist also die Geschichte von String Variable.
Schauen wir uns nun das StringBuilder-Objekt an. Beispielsweise:
In diesem Fall werden wir also dasselbe Objekt fünfmal ändern.
Die offensichtliche Frage ist also: Was passiert eigentlich unter der Haube, wenn wir den gleichen StringBuilder 5-mal ändern?
Dies passiert, wenn wir denselben StringBuilder fünfmal ändern.
Schauen wir uns die Figur an.
Erklärung: Im Fall eines StringBuilder-Objekts. Sie würden das neue Objekt nicht bekommen. Das gleiche Objekt wird im Speicher geändert. Selbst wenn Sie das Objekt ändern und beispielsweise 10.000 Mal, haben wir immer noch nur ein stringBuilder-Objekt.
Sie haben nicht viele Garbage-Objekte oder nicht referenzierte stringBuilder-Objekte, weil sie geändert werden können. Es ist veränderlich, was bedeutet, dass es sich im Laufe der Zeit ändert?
Unterschiede:
quelle
StringBuilder reduziert die Anzahl der Zuweisungen und Zuweisungen auf Kosten des zusätzlichen verwendeten Speichers. Bei ordnungsgemäßer Verwendung kann der Compiler die Notwendigkeit beseitigen, immer größere Zeichenfolgen immer wieder zuzuweisen, bis das Ergebnis gefunden wird.
vs.
quelle
Quelle: MSDN
quelle
StringBuilder
ist besser zum Aufbau eines Strings aus vielen nicht konstanten Werten.Wenn Sie eine Zeichenfolge aus vielen konstanten Werten erstellen, z. B. mehreren Wertzeilen in einem HTML- oder XML-Dokument oder anderen Textblöcken, können Sie einfach nur an dieselbe Zeichenfolge anhängen, da dies fast alle Compiler tun "Konstante Faltung", ein Prozess zum Reduzieren des Analysebaums, wenn Sie ständig manipuliert werden (wird auch verwendet, wenn Sie so etwas schreiben
int minutesPerYear = 24 * 365 * 60
). In einfachen Fällen, in denen nicht konstante Werte aneinander angehängt sind, reduziert der .NET-Compiler Ihren Code auf etwas Ähnliches wie das, was erStringBuilder
tut.Wenn Ihr Anhang vom Compiler jedoch nicht auf etwas Einfacheres reduziert werden kann, benötigen Sie eine
StringBuilder
. Wie Fizch hervorhebt, ist es wahrscheinlicher, dass dies innerhalb einer Schleife geschieht.quelle
Ich glaube, StringBuilder ist schneller, wenn Sie mehr als 4 Zeichenfolgen haben, die Sie zusammenfügen müssen. Außerdem kann es einige coole Dinge wie AppendLine tun.
quelle
In .NET ist StringBuilder immer noch schneller als das Anhängen von Zeichenfolgen. Ich bin mir ziemlich sicher, dass sie in Java nur einen StringBuffer unter der Haube erstellen, wenn Sie Strings anhängen, sodass es keinen wirklichen Unterschied gibt. Ich bin mir nicht sicher, warum sie dies in .NET noch nicht getan haben.
quelle
Betrachten Sie die traurige Tragödie des Mikrooptimierungstheaters .
quelle
Die Verwendung von Zeichenfolgen zur Verkettung kann zu einer Laufzeitkomplexität in der Größenordnung von führen
O(n^2)
.Wenn Sie a verwenden
StringBuilder
, muss viel weniger Speicher kopiert werden. Mit dem könnenStringBuilder(int capacity)
Sie die Leistung steigern, wenn Sie abschätzen können, wie groß das Finale seinString
wird. Selbst wenn Sie nicht präzise sind, müssen Sie die Kapazität wahrscheinlich nurStringBuilder
ein paar Mal erhöhen, was ebenfalls zur Leistungssteigerung beitragen kann.quelle
Ich habe erhebliche Leistungssteigerungen durch die Verwendung des
EnsureCapacity(int capacity)
Methodenaufrufs für eine Instanz vonStringBuilder
festgestellt, bevor er für einen Zeichenfolgenspeicher verwendet wurde. Normalerweise rufe ich das nach der Instanziierung in der Codezeile auf. Es hat den gleichen Effekt, als ob Sie Folgendes instanziierenStringBuilder
:Dieser Aufruf weist den benötigten Speicher im Voraus zu, wodurch bei mehreren
Append()
Vorgängen weniger Speicher zugewiesen wird . Sie müssen eine fundierte Vermutung anstellen, wie viel Speicher Sie benötigen, aber für die meisten Anwendungen sollte dies nicht zu schwierig sein. Normalerweise irre ich mich auf der Seite von etwas zu viel Gedächtnis (wir reden über 1k oder so).quelle
EnsureCapacity
unmittelbar nach derStringBuilder
Instanziierung aufzurufen . Instanziieren Sie einfach FolgendesStringBuilder
:var sb = new StringBuilder(int capacity)
.Nach den vorherigen Antworten ist das erste, was ich bei solchen Problemen immer mache, eine kleine Testanwendung zu erstellen. Führen Sie in dieser App einen Timing-Test für beide Szenarien durch und überzeugen Sie sich selbst, welcher schneller ist.
IMHO sollte das Anhängen von mehr als 500 Zeichenfolgeneinträgen auf jeden Fall StringBuilder verwenden.
quelle
String und StringBuilder sind eigentlich beide unveränderlich. Der StringBuilder verfügt über integrierte Puffer, mit denen seine Größe effizienter verwaltet werden kann. Wenn der StringBuilder die Größe ändern muss, wird er auf dem Heap neu zugewiesen. Standardmäßig ist die Größe auf 16 Zeichen festgelegt. Sie können dies im Konstruktor festlegen.
z.B.
StringBuilder sb = neuer StringBuilder (50);
quelle
Die Verkettung von Zeichenfolgen kostet Sie mehr. In Java können Sie je nach Bedarf entweder StringBuffer oder StringBuilder verwenden. Wenn Sie eine synchronisierte und threadsichere Implementierung wünschen, wählen Sie StringBuffer. Dies ist schneller als die String-Verkettung.
Wenn Sie keine synchronisierte oder Thread-sichere Implementierung benötigen, wählen Sie StringBuilder. Dies ist schneller als die String-Verkettung und auch schneller als StringBuffer, da kein Synchronisationsaufwand entsteht.
quelle
StringBuilder ist wahrscheinlich vorzuziehen. Der Grund dafür ist, dass mehr Speicherplatz als derzeit benötigt zugewiesen wird (Sie legen die Anzahl der Zeichen fest), um Platz für zukünftige Anhänge zu lassen. Dann erfordern diese zukünftigen Anhänge, die in den aktuellen Puffer passen, keine Speicherzuweisung oder Speicherbereinigung, was teuer sein kann. Im Allgemeinen verwende ich StringBuilder für die Konzentration komplexer Zeichenfolgen oder für die Mehrfachformatierung. Wenn die Daten vollständig sind, konvertiere ich sie in einen normalen String und möchte wieder ein unveränderliches Objekt.
quelle
Wenn Sie viel String-Verkettung durchführen, verwenden Sie einen StringBuilder. Wenn Sie mit einem String verketten, erstellen Sie jedes Mal einen neuen String, der mehr Speicherplatz beansprucht.
Alex
quelle
Als allgemeine Faustregel gilt: Wenn ich den Wert der Zeichenfolge mehrmals festlegen muss oder wenn Anhänge an die Zeichenfolge angehängt sind, muss es sich um einen Zeichenfolgengenerator handeln. Ich habe Anwendungen gesehen, die ich in der Vergangenheit geschrieben habe, bevor ich etwas über String-Builder gelernt habe, die einen riesigen Speicherbedarf hatten, der immer weiter zu wachsen scheint. Durch Ändern dieser Programme zur Verwendung des String Builders wurde die Speichernutzung erheblich reduziert. Jetzt schwöre ich beim String Builder.
quelle
Mein Ansatz war immer, StringBuilder zu verwenden, wenn 4 oder mehr Zeichenfolgen verkettet werden ODER wenn ich nicht weiß, wie Verkettungen stattfinden sollen.
Guter leistungsbezogener Artikel dazu hier
quelle
StringBuilder
ist wesentlich effizienter, aber Sie werden diese Leistung nur sehen, wenn Sie eine große Menge an Zeichenfolgenänderungen vornehmen.Im Folgenden finden Sie einen kurzen Codeabschnitt, der ein Beispiel für die Leistung enthält. Wie Sie sehen, sehen Sie erst dann eine deutliche Leistungssteigerung, wenn Sie in große Iterationen geraten.
Wie Sie sehen können, dauerten die 200.000 Iterationen 22 Sekunden, während die 1 Million Iterationen mit dem
StringBuilder
fast augenblicklich waren.Ergebnis des obigen Codes:
quelle
StringBuilder bietet vom Standpunkt des Speichers aus eine bessere Leistung. Bei der Verarbeitung kann der Unterschied in der Ausführungszeit vernachlässigbar sein.
quelle