Unterschied zwischen String und StringBuilder in C #

71

Was ist der Unterschied zwischen stringund StringBuilder?

Was wären auch einige Beispiele für das Verständnis?

schäbig
quelle
1
mögliches Duplikat von String vs StringBuilder
George Stocker
5
@ George: Die erste andere Frage ist eigentlich ziemlich eng und beginnt sogar mit "Ich kenne den Unterschied bereits" - etwas, das diese Frage speziell stellt .
Joey
1
@ George: Ich kann nicht glauben, dass das nicht in der verwandten Seitenleiste aufgetaucht ist.
Bill the Lizard
1
@ Johannes: Das ist besser. Ich bin damit einverstanden, dass dies nicht genau das gleiche ist wie die anderen verknüpften Fragen, aber das könnte nur daran liegen, dass diese etwas vage ist.
Bill the Lizard

Antworten:

106

Eine stringInstanz ist unveränderlich. Sie können es nicht ändern, nachdem es erstellt wurde. Jede Operation, die stattdessen die Zeichenfolge zu ändern scheint, gibt eine neue Instanz zurück:

string foo = "Foo";
// returns a new string instance instead of changing the old one
string bar = foo.Replace('o', 'a');
string baz = foo + "bar"; // ditto here

Unveränderliche Objekte haben einige nette Eigenschaften, z. B. können sie threadsübergreifend verwendet werden, ohne Synchronisierungsprobleme zu befürchten, oder Sie können einfach Ihre privaten Sicherungsfelder direkt verteilen, ohne befürchten zu müssen, dass jemand Objekte ändert, die nicht geändert werden sollten (siehe Arrays oder veränderbare Listen). die oft kopiert werden müssen, bevor sie zurückgegeben werden, wenn dies nicht erwünscht ist). Bei unachtsamer Verwendung können sie jedoch schwerwiegende Leistungsprobleme verursachen (wie fast alles andere - wenn Sie ein Beispiel aus einer Sprache benötigen, die stolz auf die Ausführungsgeschwindigkeit ist, sehen Sie sich die Funktionen zur Zeichenfolgenmanipulation von C an).

Wenn Sie eine veränderbare Zeichenfolge, wie man bist du stückweise contructing oder wo man viele Dinge ändern, dann eine die Sie benötigen , StringBuilderdie ein Puffer von Zeichen ist , die können geändert werden. Dies hat größtenteils Auswirkungen auf die Leistung. Wenn Sie eine veränderbare Zeichenfolge möchten und dies stattdessen mit einer normalen stringInstanz tun , müssen Sie am Ende viele Objekte unnötig erstellen und zerstören, während sich eine StringBuilderInstanz selbst ändert und die Notwendigkeit vieler neuer Objekte zunichte macht.

Einfaches Beispiel: Das Folgende lässt viele Programmierer vor Schmerzen zusammenzucken:

string s = string.Empty;
for (i = 0; i < 1000; i++) {
  s += i.ToString() + " ";
}

Am Ende erstellen Sie hier 2001 Zeichenfolgen, von denen 2000 weggeworfen werden. Das gleiche Beispiel mit StringBuilder:

StringBuilder sb = new StringBuilder();
for (i = 0; i < 1000; i++) {
  sb.Append(i);
  sb.Append(' ');
}

Dies sollte den Speicherzuweiser viel weniger belasten :-)

Es sollte jedoch beachtet werden, dass der C # -Compiler in Bezug auf Zeichenfolgen einigermaßen intelligent ist. Zum Beispiel die folgende Zeile

string foo = "abc" + "def" + "efg" + "hij";

wird vom Compiler verbunden, wobei zur Laufzeit nur eine einzige Zeichenfolge übrig bleibt. Ebenso Linien wie

string foo = a + b + c + d + e + f;

wird umgeschrieben in

string foo = string.Concat(a, b, c, d, e, f);

Sie müssen also nicht für fünf unsinnige Verkettungen bezahlen, was die naive Art wäre, damit umzugehen. Dies wird Sie nicht in Schleifen wie oben speichern (es sei denn, der Compiler rollt die Schleife ab, aber ich denke, nur die JIT kann dies tatsächlich tun und besser nicht darauf wetten).

Joey
quelle
"Jede Operation, die stattdessen die Zeichenfolge zu ändern scheint, gibt eine neue Instanz zurück", aber warum? was ist der Grund?? Warum ist String nicht veränderlich? Warum CLR neue Instanz erstellen und vorherige Instanz löschen?
AminM
5
@Jeson: Unveränderliche Datenstrukturen haben viele nette Eigenschaften, von denen die meisten standardmäßig mit dem Schreiben von sichererem Code zusammenhängen. Sie müssen sich keine Sorgen machen, dass sich Ihre Zeichenfolgen ändern, nur weil ein anderer Thread daran arbeitet. Und Sie müssen keine Kopien der internen Zeichenfolgen einer Klasse zurückgeben, um zu verhindern, dass Verbraucher Ihre Felder manipulieren.
Joey
8

String vs. StringBuilder

  • String

    • Unter System-Namespace

    • Unveränderliche (schreibgeschützte) Instanz

    • Die Leistung nimmt ab, wenn eine kontinuierliche Wertänderung auftritt

    • Gewindesicher

  • StringBuilder (veränderbarer String)

    1. Unter System.Text-Namespace
    2. Veränderliche Instanz
    3. Zeigt eine bessere Leistung, da neue Änderungen an einer vorhandenen Instanz vorgenommen werden

Folgen Sie diesem Link , um einen beschreibenden Artikel zu diesem Thema mit vielen Beispielen für die Verwendung von ObjectIDGenerator zu erhalten .

Verwandte Frage zum Stapelüberlauf : Veränderbarkeit der Zeichenfolge, wenn sich die Zeichenfolge in C # nicht ändert

Shamseer K.
quelle
6

String ist unveränderlich, was bedeutet, dass Sie beim Erstellen eines Strings diesen niemals ändern können. Vielmehr wird eine neue Zeichenfolge zum Speichern des neuen Werts erstellt. Dies kann ineffizient sein, wenn Sie den Wert einer Zeichenfolgenvariablen häufig ändern müssen.

StringBuilder kann verwendet werden, um eine veränderbare Zeichenfolge zu simulieren. Dies ist daher hilfreich, wenn Sie eine Zeichenfolge häufig ändern müssen.

Hans Olsson
quelle
4

String

Eine String-Instanz ist unveränderlich, dh wir können sie nach ihrer Erstellung nicht mehr ändern. Wenn wir eine Operation für einen String ausführen, wird eine neue Instanz zurückgegeben (erstellt eine neue Instanz im Speicher), anstatt den vorhandenen Instanzwert zu ändern.

StringBuilder

StringBuilder ist veränderbar. Wenn wir also eine Operation für StringBuilder ausführen, wird der vorhandene Instanzwert aktualisiert und keine neue Instanz erstellt.

Unterschied zwischen String und StringBuilder

RAM
quelle
2

Aus der Dokumentation zur StringBuilder-Klasse :

Das String-Objekt ist unveränderlich. Jedes Mal, wenn Sie eine der Methoden in der System.String-Klasse verwenden, erstellen Sie ein neues Zeichenfolgenobjekt im Speicher, für das eine neue Speicherplatzzuweisung für dieses neue Objekt erforderlich ist. In Situationen, in denen Sie wiederholt Änderungen an einer Zeichenfolge vornehmen müssen, kann der mit dem Erstellen eines neuen Zeichenfolgenobjekts verbundene Aufwand kostspielig sein. Die System.Text.StringBuilder-Klasse kann verwendet werden, wenn Sie eine Zeichenfolge ändern möchten, ohne ein neues Objekt zu erstellen. Die Verwendung der StringBuilder-Klasse kann beispielsweise die Leistung steigern, wenn viele Zeichenfolgen in einer Schleife miteinander verknüpft werden.

Bill die Eidechse
quelle
2

Ein StringBuilder hilft Ihnen, wenn Sie Strings in mehreren Schritten erstellen müssen.

Anstatt dies zu tun:

String x = "";
x += "first ";
x += "second ";
x += "third ";

Sie machen

StringBuilder sb = new StringBuilder("");
sb.Append("first ");
sb.Append("second ");
sb.Append("third");
String x = sb.ToString();

Der endgültige Effekt ist der gleiche, aber der StringBuilder benötigt weniger Speicher und wird schneller ausgeführt. Anstatt eine neue Zeichenfolge zu erstellen, die die Verkettung der beiden darstellt, werden die Chunks separat erstellt und erst am Ende werden sie vereint.

Palantir
quelle
1

Hauptunterschied:

String ist unveränderlich. Dies bedeutet, dass Sie eine Zeichenfolge überhaupt nicht ändern können. Das Ergebnis der Änderung ist eine neue Zeichenfolge. Dies ist nicht effektiv, wenn Sie an eine Zeichenfolge anhängen möchten.

StringBuilder ist veränderbar. Es kann auf jede Weise geändert werden und erfordert keine Erstellung einer neuen Instanz. Wenn die Arbeit erledigt ist, kann ToString () aufgerufen werden, um die Zeichenfolge abzurufen.

Strings können am Praktikum teilnehmen. Dies bedeutet, dass Zeichenfolgen mit demselben Inhalt dieselben Adressen haben können. StringBuilder kann nicht interniert werden.

String ist die einzige Klasse, die ein Referenzliteral haben kann.

Andrey
quelle
1

Zeichenfolgen sind unveränderlich, dh wenn Sie ihren Wert ändern, wird der alte Wert verworfen und ein neuer Wert auf dem Heap erstellt, während wir im Zeichenfolgen-Generator den vorhandenen Wert ändern können, ohne dass der neue Wert erstellt wird.

In Bezug auf die Leistung ist der String Builder daher von Vorteil, da wir unnötigerweise nicht mehr Speicherplatz belegen.

Nitin Nayyar
quelle
0

Ein String (System.String) ist ein Typ, der im .NET Framework definiert ist. Die String-Klasse ist nicht veränderbar. Dies bedeutet, dass der .NET-Compiler jedes Mal, wenn Sie eine Aktion für eine System.String-Instanz ausführen, eine neue Instanz der Zeichenfolge erstellt. Dieser Vorgang ist dem Entwickler verborgen.

Ein System.Text.StringBuilder ist eine Klasse, die eine veränderbare Zeichenfolge darstellt. Diese Klasse bietet einige nützliche Methoden, mit denen der Benutzer den vom StringBuilder umschlossenen String verwalten kann. Beachten Sie, dass alle Manipulationen an derselben StringBuilder-Instanz vorgenommen werden.

Microsoft empfiehlt die Verwendung von StringBuilder, da es hinsichtlich der Speichernutzung effektiver ist.

AngeloBad
quelle
0

Auch die Komplexität der Verkettungen von String ist O (N2), während sie für StringBuffer O (N) ist.

Daher kann es zu Leistungsproblemen kommen, wenn wir Verkettungen in Schleifen verwenden, da jedes Mal viele neue Objekte erstellt werden.

Vinay Lodha
quelle
0

Sie können die CloneMethode verwenden, wenn Sie Zeichenfolgen zusammen mit dem Zeichenfolgengenerator durchlaufen möchten. Sie gibt ein Objekt zurück, sodass Sie es mit der ToString-Methode in eine Zeichenfolge konvertieren können ... :)

user2440156
quelle
0

System.String ist ein veränderbares Objekt, dh es kann nach seiner Erstellung nicht mehr geändert werden. Weitere Informationen finden Sie unter Unterschied zwischen String und StringBuilder in C #. zum besseren Verständnis.

Amila Munasinghe
quelle
1
Bitte fügen Sie einige Inhalte von th elink
Robert
0

Ein String ist ein unveränderlicher Typ. Dies bedeutet, dass Sie jedes Mal, wenn Sie Zeichenfolgen miteinander verketten, jedes Mal neue Zeichenfolgen erstellen. Wenn Sie dies so oft tun, entsteht viel Heap-Overhead und das Risiko, dass Ihnen der Speicher ausgeht.

Eine StringBuilder-Instanz wird verwendet, um Zeichenfolgen an dieselbe Instanz anzuhängen und eine Zeichenfolge zu erstellen, wenn Sie die ToString-Methode aufrufen.

Aufgrund des Overheads beim Instanziieren eines StringBuilder-Objekts wird von Microsoft angegeben, dass es nützlich ist, wenn Sie mehr als 5-10 Zeichenfolgenverkettungen haben.

Für Beispielcode schlage ich vor, dass Sie hier einen Blick darauf werfen:

Kris van der Mast
quelle