Warum erstellt .NET neue Teilzeichenfolgen, anstatt in vorhandene Zeichenfolgen zu zeigen?

7

Aus einem kurzen Blick mit Reflector sieht es so aus, als ob String.Substring() Speicher für jeden Teilstring reserviert. Habe ich Recht, dass dies der Fall ist? Ich dachte, das wäre nicht notwendig, da Strings unveränderlich sind.

Mein Ziel war es, eine IEnumerable<string> Split(this String, Char) Erweiterungsmethode zu erstellen, die keinen zusätzlichen Speicher zuweist.

    
foson 04.07.2009, 15:42
quelle

5 Antworten

22

Ein Grund, warum die meisten Sprachen mit unveränderlichen Strings neue Teilstrings erzeugen, anstatt auf existierende Strings zu verweisen, liegt daran, dass dies die spätere Sammlung von Strings beeinträchtigt.

Was passiert, wenn ein String für seinen Teilstring verwendet wird, aber dann der größere String unerreichbar wird (außer durch den Teilstring). Die größere Zeichenfolge ist nicht abrufbar, da dies die Teilzeichenfolge ungültig machen würde. Was auf kurze Sicht eine gute Möglichkeit war, Speicher zu sparen, wird auf lange Sicht zu einem Speicherleck.

    
SingleNegationElimination 04.07.2009, 16:29
quelle
2
___ answer 1082456 ___

Nicht möglich, ohne innerhalb von .net mit String-Klassen herumzustochern. Sie müssten Referenzen auf ein Array weitergeben, das änderbar ist und sicherstellen, dass niemand vermasselt wird.

.Net erstellt jedes Mal eine neue Zeichenfolge, wenn Sie danach gefragt werden. Einzige Ausnahme hiervon sind internierte Strings, die vom Compiler erstellt werden (und von Ihnen erledigt werden können), die einmal in den Speicher geladen werden und dann aus Speicher- und Performance-Gründen Zeiger auf den String gesetzt werden.

    
___ qstntxt ___

Aus einem kurzen Blick mit Reflector sieht es so aus, als ob %code% Speicher für jeden Teilstring reserviert. Habe ich Recht, dass dies der Fall ist? Ich dachte, das wäre nicht notwendig, da Strings unveränderlich sind.

Mein Ziel war es, eine %code% Erweiterungsmethode zu erstellen, die keinen zusätzlichen Speicher zuweist.

    
___ answer1082525 ___

Ein Grund, warum die meisten Sprachen mit unveränderlichen Strings neue Teilstrings erzeugen, anstatt auf existierende Strings zu verweisen, liegt daran, dass dies die spätere Sammlung von Strings beeinträchtigt.

Was passiert, wenn ein String für seinen Teilstring verwendet wird, aber dann der größere String unerreichbar wird (außer durch den Teilstring). Die größere Zeichenfolge ist nicht abrufbar, da dies die Teilzeichenfolge ungültig machen würde. Was auf kurze Sicht eine gute Möglichkeit war, Speicher zu sparen, wird auf lange Sicht zu einem Speicherleck.

    
___ answer1082495 ___

Jeder String muss eigene String-Daten haben, so wie die String-Klasse implementiert ist.

Sie können Ihre eigene SubString-Struktur erstellen, die einen Teil einer Zeichenfolge verwendet:

%Vor%

Sie können es mit anderen Methoden wie Vergleich, die auch ohne das Extrahieren der Zeichenfolge möglich ist, ausarbeiten.

    
___ tag123c ___ C # (sprich "Cis") ist eine objektorientierte Programmiersprache auf hohem Niveau, die für die Erstellung einer Vielzahl von Anwendungen entwickelt wurde, die auf dem .NET Framework (oder .NET Core) ausgeführt werden. C # ist einfach, leistungsfähig, typsicher und objektorientiert. ___ tag123net ___ Das .NET-Framework ist ein Software-Framework, das hauptsächlich für das Microsoft Windows-Betriebssystem entwickelt wurde. Es enthält eine Implementierung der Basisklassenbibliothek, Common Language Runtime (allgemein als CLR bezeichnet), Common Type System (allgemein als CTS bezeichnet) und Dynamic Language Runtime. Es unterstützt viele Programmiersprachen, einschließlich C #, VB.NET, F # und C ++ / CLI. NICHT für Fragen zu .NET Core verwenden. ___ answer1082473 ___

Da Zeichenfolgen in .NET unveränderlich sind, weist jede Zeichenfolgenoperation, die zu einem neuen Zeichenfolgenobjekt führt, einen neuen Speicherblock für den Zeichenfolgeninhalt zu.

Theoretisch könnte es möglich sein, den Speicher beim Extrahieren einer Teilzeichenfolge wiederzuverwenden, aber das würde die Speicherbereinigung sehr kompliziert machen: Was ist, wenn die ursprüngliche Zeichenkette durch Müll gesammelt wird? Was würde mit der Teilzeichenkette passieren, die ein Teil davon teilt?

Natürlich verhindert nichts, dass das .NET BCL-Team dieses Verhalten in zukünftigen .NET-Versionen ändern kann. Es hätte keine Auswirkungen auf den vorhandenen Code.

    
___ answer1082851 ___

Hinzufügen zu dem Punkt, dass Strings unveränderlich sind, sollten Sie sein, dass das folgende Snippet mehrere String-Instanzen im Speicher generiert.

%Vor%

s1 + s2 = & gt; Neue String-Instanz (temp1)

temp1 + s3 = & gt; neue String-Instanz (temp2)

res ist eine Referenz auf temp2. ​​

    
___ tag123string ___ Eine Zeichenfolge ist eine endliche Abfolge von Symbolen, die üblicherweise für Text verwendet wird, manchmal jedoch auch für beliebige Daten. ___ tag123memory ___ Verwenden Sie dieses Tag für die Speicherverwaltung oder Probleme beim Programmieren. Bei Fragen zu Speicherhardwareproblemen oder Fehlern in allgemeiner Software rufen Sie https://superuser.com oder https://serverfault.com auf, wenn dies mit Hardware oder Software auf Unternehmensebene zu tun hat. ___ qstnhdr ___ Warum erstellt .NET neue Teilzeichenfolgen, anstatt in vorhandene Zeichenfolgen zu zeigen? ___ tag123stringinterning ___ Ein String-Pool ermöglicht einer Laufzeit, Speicher zu sparen, indem unveränderliche Zeichenfolgen in einem Pool beibehalten werden, sodass Instanzen von allgemeinen Zeichenfolgen in der gesamten Anwendung wiederverwendet werden können, anstatt mehrere Instanzen derselben zu erstellen. ___
Spence 04.07.2009 15:49
quelle
1

Jeder String muss eigene String-Daten haben, so wie die String-Klasse implementiert ist.

Sie können Ihre eigene SubString-Struktur erstellen, die einen Teil einer Zeichenfolge verwendet:

%Vor%

Sie können es mit anderen Methoden wie Vergleich, die auch ohne das Extrahieren der Zeichenfolge möglich ist, ausarbeiten.

    
Guffa 04.07.2009 16:08
quelle
0

Da Zeichenfolgen in .NET unveränderlich sind, weist jede Zeichenfolgenoperation, die zu einem neuen Zeichenfolgenobjekt führt, einen neuen Speicherblock für den Zeichenfolgeninhalt zu.

Theoretisch könnte es möglich sein, den Speicher beim Extrahieren einer Teilzeichenfolge wiederzuverwenden, aber das würde die Speicherbereinigung sehr kompliziert machen: Was ist, wenn die ursprüngliche Zeichenkette durch Müll gesammelt wird? Was würde mit der Teilzeichenkette passieren, die ein Teil davon teilt?

Natürlich verhindert nichts, dass das .NET BCL-Team dieses Verhalten in zukünftigen .NET-Versionen ändern kann. Es hätte keine Auswirkungen auf den vorhandenen Code.

    
Philippe Leybaert 04.07.2009 15:55
quelle
0

Hinzufügen zu dem Punkt, dass Strings unveränderlich sind, sollten Sie sein, dass das folgende Snippet mehrere String-Instanzen im Speicher generiert.

%Vor%

s1 + s2 = & gt; Neue String-Instanz (temp1)

temp1 + s3 = & gt; neue String-Instanz (temp2)

res ist eine Referenz auf temp2. ​​

    
Babak Naffas 04.07.2009 19:41
quelle