Sind JavaScript-Strings unveränderbar? Benötige ich einen “String Builder” in JavaScript?

Verwendet Javascript unveränderliche oder veränderbare Zeichenfolgen? Brauche ich einen “String Builder”?

Solutions Collecting From Web of "Sind JavaScript-Strings unveränderbar? Benötige ich einen “String Builder” in JavaScript?"

Sie sind unveränderlich. Sie können ein Zeichen in einer Zeichenfolge nicht ändern, var myString = "abbdef"; myString[2] = 'c' etwas wie var myString = "abbdef"; myString[2] = 'c' var myString = "abbdef"; myString[2] = 'c' . Die Methoden zur Zeichenfolgemanipulation, wie zum Beispiel trim , slice geben neue Zeichenfolgen zurück.

Allerdings habe ich immer gehört, was Ash in seiner Antwort erwähnt hat (dass die Verwendung von Array.join schneller ist für die Verkettung), also wollte ich die verschiedenen Methoden der Verkettung von Strings testen und den schnellsten Weg zu einem StringBuilder abstrahieren. Ich habe ein paar Tests geschrieben, um zu sehen, ob das stimmt (ist es nicht!).

Das war, was ich für den schnellsten Weg hielt, obwohl ich immer wieder dachte, dass das Hinzufügen eines Methodenaufrufs es vielleicht langsamer machen könnte …

 function StringBuilder() { this._array = []; this._index = 0; } StringBuilder.prototype.append = function (str) { this._array[this._index] = str; this._index++; } StringBuilder.prototype.toString = function () { return this._array.join(''); } 

Hier sind performancesgeschwindigkeitstests. Alle drei kreieren eine gigantische Saite, die aus dem zusammenhängenden "Hello diggity dog" hunderttausendmal zu einer leeren Saite wird.

Ich habe drei Arten von Tests erstellt

  • Verwenden von Array.push und Array.join
  • Verwenden Sie die Array-Indizierung, um Array.push zu vermeiden, und verwenden Array.join dann Array.join
  • Straight String Verkettung

Dann habe ich die gleichen drei Tests erstellt, indem ich sie in StringBuilderConcat , StringBuilderArrayPush und StringBuilderArrayIndex abstrahiere http://jsperf.com/string-concat-without-sringbuilder/5 Bitte gehen Sie dorthin und führen Sie Tests durch, damit wir ein schönes Beispiel bekommen können. Beachten Sie, dass ich einen kleinen Fehler behoben habe, so dass die Daten für die Tests gelöscht wurden. Ich werde die Tabelle aktualisieren, sobald genügend performancesdaten vorliegen. Rufen Sie http://jsperf.com/string-concat-without-sringbuilder/5 für die alte Datentabelle auf.

Hier einige Zahlen vom 21. Februar 2013, wenn Sie dem Link nicht folgen möchten. Die Nummer bei jedem Test ist in Operationen / Sekunde ( höher ist besser )

 | Browser | Index | Push | Concat | SBIndex | SBPush | SBConcat | --------------------------------------------------------------------------- | Chrome 24.0.1312 | 83 | 87 | 702 | 69 | 87 | 165 | | Chrome 25.0.1364 | 43 | 47 | 620 | 42 | 42 | 68 | | Firefox 10.0.10 | 164 | 164 | 533 | 164 | 16 | 421 | | Firefox 19.0 | 70 | 70 | 259 | 70 | 70 | 186 | | Exploder 7.0 | 51 | 33 | 58 | 31 | 37 | 45 | | Exploder 8.0 | 48 | 30 | 58 | 30 | 36 | 36 | | Exploder 9.0 | 87 | 64 | 95 | 61 | 61 | 61 | | Opera 12.14 | 125 | 154 | 66 | 106 | 137 | 63 | 

Ergebnisse

  • Heutzutage verarbeiten alle Browser die String-Verkettung gut. Array.join hilft nur Opera

  • Insgesamt ist Chrome am schnellsten und taktet 1025 Ops / Sek. In 27,0. 10 mal schneller als mit Array.join ()

  • Firefox ist an zweiter Stelle bei etwa 550 Ops / Sek. (Aber 20,0 scheint sich zurückgebildet zu haben). Array.join ist 4-5 mal langsamer.

  • IE ist am schnellsten mit geraden String-Verkettungen, es ist sehr langsam mit Array.join und Array.push . IE 9 macht Array.join nicht so langsam, und alle SB-Abstraktionen Array.join sich fast gleich (wahrscheinlich wegen des Methoden-Overheads)

  • Opera ist die einzige, bei der das Array.join tatsächlich hilft, es ist 2-3 mal so schnell wie eine String-Verkettung.

  • Das Erstellen eines StringBuilders, der die Performance-Probleme jedes Browsers abstrahiert, schadet mehr als nützt. Der Overhead von Methodenaufrufen mag akzeptabel sein, aber die Tendenz scheint zu sein, dass Browser String-Verkettungen intelligenter handhaben. Es macht nur Sinn, wenn Ihre Zielgruppe Opera ist, also können Sie Array.join dort verwenden und String-Verkettungen überall sonst verwenden (das bedeutet, alle anderen Browser nehmen einen Treffer)

Hoffe, jemand anderes findet das nützlich

Anderer Testfall

Da @RoyTinker dachte, dass mein Test errorshaft war, habe ich einen neuen Fall erstellt, der keine große Zeichenfolge durch Verketten derselben Zeichenfolge erstellt, sondern für jede Iteration ein anderes Zeichen verwendet. Die Stringverkettung schien immer noch schneller oder genauso schnell. Lass uns diese Tests laufen lassen.

Ich schlage vor, jeder sollte über andere Wege nachdenken, um dies zu testen, danke für die Eingabe Roy.

http://jsperf.com/string-concat-without-sringbuilder/7

aus dem Nashornbuch :

In JavaScript sind Zeichenfolgen unveränderliche Objekte, was bedeutet, dass die Zeichen in ihnen nicht geändert werden dürfen und dass alle Operationen in Zeichenfolgen tatsächlich neue Zeichenfolgen erstellen. Zeichenfolgen werden als Referenz zugewiesen, nicht als Wert. Wenn ein Objekt durch Referenz zugewiesen wird, wird eine Änderung, die über eine Referenz an dem Objekt vorgenommen wird, im Allgemeinen durch alle anderen Referenzen auf das Objekt sichtbar. Da Zeichenfolgen jedoch nicht geändert werden können, können Sie mehrere Verweise auf ein Zeichenfolgenobjekt haben und sich nicht sorgen, dass sich der Zeichenfolgenwert ohne Ihr Wissen ändert

performancestipp:

Wenn Sie große Zeichenfolgen verketten müssen, Array.Join() die Zeichenfolgenelemente in ein Array ein und verwenden Sie die Array.Join() -Methode, um die gesamte Zeichenfolge Array.Join() . Dies kann um ein Vielfaches schneller sein, um eine große Anzahl von Strings zu verketten.

Es gibt keinen StringBuilder in JavaScript.

JavaScript-Strings sind tatsächlich unveränderbar.

Der String-Typ-Wert ist unveränderlich, aber das String-Objekt, das mit dem Konstruktor String () erstellt wird, ist veränderbar, da es ein Objekt ist und Sie ihm neue Eigenschaften hinzufügen können.

 > var str = new String("test") undefined > str [String: 'test'] > str.newProp = "some value" 'some value' > str { [String: 'test'] newProp: 'some value' } 

Obwohl Sie neue Eigenschaften hinzufügen können, können Sie die bereits vorhandenen Eigenschaften nicht ändern

Ein Screenshot eines Tests in der Chrome-Konsole

Zusammenfassend ist 1. der Wert aller Zeichenketten (primitiver Typ) unveränderlich. 2. Das String-Objekt ist veränderbar, aber der String-Typ-Wert (primitiver Typ), den es enthält, ist unveränderlich.

Strings in Javascript sind unveränderlich

In Bezug auf Ihre Frage (in Ihrem Kommentar zu Ashs Antwort) über den StringBuilder in ASP.NET Ajax scheinen die Experten in diesem Punkt anderer Meinung zu sein.

Christian Wenz sagt in seinem Buch Programming ASP.NET AJAX (O’Reilly), dass “dieser Ansatz keinen messbaren Effekt auf das Gedächtnis hat (tatsächlich scheint die Implementierung ein Tick langsamer zu sein als der Standardansatz).”

Auf der anderen Seite sagen Gallo et al. In ihrem Buch ASP.NET AJAX in Action (Manning): “Wenn die Anzahl der zu verkettenden Strings größer ist, wird der String Builder zu einem essentiellen Objekt, um große performanceseinbußen zu vermeiden.”

Ich denke, Sie müssten Ihr eigenes Benchmarking durchführen und die Ergebnisse könnten sich auch zwischen den Browsern unterscheiden. Auch wenn es die performance nicht verbessert, kann es dennoch als “nützlich” für Programmierer angesehen werden, die es gewohnt sind, mit StringBuilders in Sprachen wie C # oder Java zu codieren.

Strings sind unveränderlich – sie können sich nicht ändern, wir können immer nur neue Strings machen.

Beispiel:

 var str= "Immutable value"; // it is immutable var other= statement.slice(2, 10); // new string 

Es ist ein später Post, aber ich fand kein gutes Buch unter den Antworten.

Hier ist eine bestimmte Ausnahme von einem zuverlässigen Buch:

Zeichenfolgen sind in ECMAScript unveränderlich, was bedeutet, dass sich ihre Werte nach der Erstellung nicht ändern können. Um die Zeichenfolge einer Variablen zu ändern, muss die ursprüngliche Zeichenfolge gelöscht und die Variable mit einer anderen Zeichenfolge gefüllt werden, die einen neuen Wert enthält … – Professionelles JavaScript für Webentwickler, 3. Auflage, S.43

Nun, die Antwort, die den Auszug des Rhino-Buchs zitiert, ist richtig bezüglich der Unveränderbarkeit der Zeichenkette, aber falsch gesagt: “Zeichenketten werden per Referenz zugewiesen, nicht nach Wert.” (Wahrscheinlich hatten sie ursprünglich vor, die Wörter in eine entgegengesetzte Richtung zu bringen).

Das Missverständnis “Referenz / Wert” wird im “Professional JavaScript”, Kapitel “Primitive und Referenzwerte” verdeutlicht:

Die fünf primitiven Typen … [sind]: Nicht definiert, Null, Boolean, Number und String. Auf diese Variablen wird nach Wert zugegriffen, da Sie den tatsächlichen Wert manipulieren, der in der Variablen gespeichert ist. – Professionelles JavaScript für Webentwickler, 3. Ausgabe, S.85

das ist gegen Objekte :

Wenn Sie ein Objekt manipulieren, arbeiten Sie wirklich an einem Verweis auf dieses Objekt und nicht an dem eigentlichen Objekt. Aus diesem Grund wird gesagt, dass solche Werte durch Bezugnahme zugegriffen werden. – Professionelles JavaScript für Webentwickler, 3. Ausgabe, S.85