Heute habe ich diesen Thread über die Geschwindigkeit der Verkettung von Zeichenfolgen gelesen .
Überraschenderweise war die Verkettung von Zeichenfolgen der Gewinner:
Das Ergebnis war das Gegenteil von dem, was ich dachte. Außerdem gibt es viele Artikel über diese , die wie entgegengesetzt zu erklären dies .
Ich kann mir vorstellen, dass Browser so optimiert sind, dass sie concat
auf der neuesten Version angezeigt werden , aber wie machen sie das? Können wir sagen, dass es besser ist, +
Zeichenfolgen zu verketten?
Aktualisieren
So wird in modernen Browsern String - Verkettung so optimiert, mit +
Zeichen ist schneller als die Verwendung , join
wenn Sie möchten , verketten Saiten.
Aber @Arthur wies darauf hin , dass join
schneller ist , wenn Sie tatsächlich wollen beitreten Strings mit einem Separator.
Update - 2020
Chrome: Array join
ist fast 2 times faster
String concat +
Siehe: https://stackoverflow.com/a/54970240/984471
Als Hinweis:
- Array
join
ist besser, wenn Sie habenlarge strings
- Wenn wir
several small strings
in der endgültigen Ausgabe generieren müssen , ist es besser, mit string concat zu arbeiten+
, da andernfalls für Array am Ende mehrere Konvertierungen von Array zu String erforderlich sind , was zu einer Leistungsüberlastung führt.
quelle
Antworten:
Die V8-Javascript-Engine (in Google Chrome verwendet) verwendet diesen Code, um die Verkettung von Zeichenfolgen durchzuführen:
Intern optimieren sie es also, indem sie ein InternalArray (die
parts
Variable) erstellen , das dann gefüllt wird. Die StringBuilderConcat-Funktion wird mit diesen Teilen aufgerufen. Es ist schnell, weil die StringBuilderConcat-Funktion stark optimierter C ++ - Code ist. Es ist zu lang, um hier zu zitieren, aber suchen Sie in der Datei runtime.ccRUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat)
nach dem Code.quelle
arr.join vs str+
Sie auf Chrom (in Operationen pro Sekunde)25k/s vs 52k/s
. auf Firefox neu bekommt man76k/s vs 212k/s
. sostr+
ist SCHNELLER. aber schauen wir uns andere Browser an. Opera gibt 43k / s vs 26k / s. IE gibt1300/s vs 1002/s
. Schau was passiert? Der einzige Browser, der eine Optimierung benötigt, ist besser dran, wenn er das verwendet, was bei allen anderen langsamer ist, wo es überhaupt keine Rolle spielt. Keiner dieser Artikel versteht etwas über Leistung.Firefox ist schnell, weil es sogenannte Seile verwendet ( Seile: eine Alternative zu Strings ). Ein Seil ist im Grunde nur eine DAG, bei der jeder Knoten eine Schnur ist.
Wenn Sie dies beispielsweise tun würden
a = 'abc'.concat('def')
, würde das neu erstellte Objekt folgendermaßen aussehen. Natürlich sieht das im Speicher nicht genau so aus, da Sie noch ein Feld für den Zeichenfolgentyp, die Länge und möglicherweise ein anderes benötigen.Und
b = a.concat('123')
Im einfachsten Fall muss die VM also fast keine Arbeit leisten. Das einzige Problem ist, dass dies andere Operationen an der resultierenden Zeichenfolge etwas verlangsamt. Auch dies reduziert natürlich den Speicheraufwand.
Auf der anderen Seite
['abc', 'def'].join('')
würde normalerweise nur Speicher zugewiesen, um die neue Zeichenfolge flach im Speicher auszulegen. (Vielleicht sollte dies optimiert werden)quelle
Ich weiß, dass dies ein alter Thread ist, aber Ihr Test ist falsch. Sie tun,
output += myarray[i];
während es eher so sein sollte,output += "" + myarray[i];
weil Sie vergessen haben, dass Sie Gegenstände mit etwas zusammenkleben müssen. Der Concat-Code sollte ungefähr so lauten:Auf diese Weise führen Sie zwei Operationen anstelle einer durch, indem Sie Elemente zusammenkleben.
Array.join()
ist schneller.quelle
"" +
und Original?output
ohne.Array.join(",")
was mit Ihrerfor
Schleife nicht funktioniertBei großen Datenmengen ist die Verknüpfung schneller, sodass die Frage falsch angegeben wird.
Getestet auf Chrome 72.0.3626.119, Firefox 65.0.1, Edge 42.17134.1.0. Beachten Sie, dass es auch mit der enthaltenen Array-Erstellung schneller geht!
quelle
Die Benchmarks dort sind trivial. Das wiederholte Verketten derselben drei Elemente wird eingefügt, die Ergebnisse werden als deterministisch und gespeichert gespeichert, der Garbage Handler wird nur Array-Objekte (die so gut wie nichts in der Größe haben) wegwerfen und wahrscheinlich nur aufgrund von Nein vom Stapel gestoßen und geknallt externe Referenzen und weil sich die Zeichenfolgen nie ändern. Ich wäre beeindruckter, wenn der Test eine große Anzahl zufällig generierter Zeichenfolgen wäre. Wie bei ein oder zwei Konzerten.
Array.join FTW!
quelle
Ich würde sagen, dass es mit Strings einfacher ist, einen größeren Puffer vorab zuzuweisen. Jedes Element besteht nur aus 2 Bytes (wenn UNICODE). Selbst wenn Sie konservativ sind, können Sie der Zeichenfolge einen ziemlich großen Puffer zuweisen. Mit
arrays
jedem Element ist mehr „Komplex“, weil jedes Element ein istObject
, so dass eine konservative Umsetzung Raum für weniger Elemente preallocate wird.Wenn Sie versuchen,
for(j=0;j<1000;j++)
vor jedem ein hinzuzufügen, werdenfor
Sie feststellen, dass (unter Chrom) der Geschwindigkeitsunterschied kleiner wird. Am Ende war es noch 1,5x für die String-Verkettung, aber kleiner als die 2,6, die vorher war.UND wenn die Elemente kopiert werden müssen, ist ein Unicode-Zeichen wahrscheinlich kleiner als ein Verweis auf ein JS-Objekt.
Beachten Sie, dass es die Möglichkeit gibt, dass viele Implementierungen von JS-Engines eine Optimierung für Single-Type-Arrays haben, die alles, was ich geschrieben habe, unbrauchbar macht :-)
quelle
Dieser Test zeigt die Strafe für die tatsächliche Verwendung einer Zeichenfolge, die mit Zuordnungsverkettung erstellt wurde, im Vergleich zur Verwendung der Methode array.join. Die Gesamtzuweisungsgeschwindigkeit ist in Chrome v31 zwar immer noch doppelt so hoch, aber nicht mehr so hoch wie bei Nichtverwendung der resultierenden Zeichenfolge.
quelle
Dies hängt eindeutig von der Implementierung der Javascript-Engine ab. Selbst für verschiedene Versionen eines Motors können Sie signifikant unterschiedliche Ergebnisse erzielen. Sie sollten Ihren eigenen Benchmark durchführen, um dies zu überprüfen.
Ich würde sagen, dass dies
String.concat
in den letzten Versionen von V8 eine bessere Leistung bietet. Aber für Firefox und OperaArray.join
ist ein Gewinner.quelle
Ich vermute, dass, während jede Version die Kosten vieler Verkettungen trägt, die Join-Versionen zusätzlich Arrays erstellen.
quelle