Läuft die HTML-Codegenerierung in modernen Browsern messbar schneller, wenn in ES6 Zeichenfolgenverkettung oder Vorlagenliterale verwendet werden?
Zum Beispiel:
String-Verkettung
"<body>"+
"<article>"+
"<time datetime='" + date.toISOString() +"'>"+ date +"</time>"+
"</article>"+
"</body>"
Vorlagenliteral
`<body>
<article>
<time datetime='${ date.toISOString() }'>${ date }</time>
</article>
</body>`
javascript
string
performance
templates
ecmascript-6
Hurrymaplelad
quelle
quelle
Antworten:
Momentan scheint die Verkettung von Zeichenfolgen schneller zu sein: http://jsperf.com/es6-string-literals-vs-string-concatenation
Ich habe getestet, dass es auf Chrome 43.0.2334.0 Canary (64-Bit) ausgeführt wurde, das V8 4.3.31 mit
#enable-javascript-harmony
aktiviertem Flag verwendet.Als Referenz verwendet die neueste Version auf Node.js (0.12.0 zum Zeitpunkt des Schreibens) V8 3.28.73: https://raw.githubusercontent.com/joyent/node/master/ChangeLog
Ich bin sicher, dass alle möglichen Leistungsoptimierungen, die angewendet werden könnten, noch nicht angewendet wurden. Es ist daher vernünftig zu erwarten, dass die Leistung verbessert wird, wenn sich ES6 der Finalisierung nähert und diese Funktionen in den stabilen Zweig migriert werden.
Bearbeiten: Danke für die Kommentare @ user1329482, @ icl7126, Nicolai Borisik und FesterCluck. Nachdem diese Frage seit ungefähr zwei Jahren gestellt wurde, hat die Unterstützung für ES6-Browser erheblich zugenommen, und es wurden zahlreiche Leistungsoptimierungen durchgeführt. Hier sind einige Updates .
Bearbeiten: (Februar 2020) Aktualisiertes Chrome-Ergebnis basierend auf @ JorgeFuentesGonzález-Kommentaren und nachfolgender Bestätigung .
In Chrome (Stand 59.0.3035) sind ES6-Zeichenfolgenliterale schneller :
Update: In Chrome (Stand 79.0.3945) ist die Verkettung von Zeichenfolgen schneller ... Siehe Kommentare.
In Firefox (ab 57.0.0) sind ES6-Zeichenfolgenliterale schneller :
In Safari (ab 11.0.2) kommt es darauf an:
Bei Verwendung einer typisierten Zeichenfolge sind ES6-Zeichenfolgenliterale schneller . Wenn Sie jedoch eine Funktion aus dem Literal aufrufen, ist die Verkettung von Zeichenfolgen in diesem Beispiel schneller .
Wenn Sie wirklich tief gehen und jeden Leistungsabfall aus Safari herausholen möchten, würde ich empfehlen, Tests einzurichten, die feststellen, ob / wie falsch eingegebene Variablen und mehrere Referenzen innerhalb einer Leistung mit wörtlichen Effekten liegen.
quelle
Ich habe einen naiven Test auf node.js v6.0.0 durchgeführt und fast die gleiche Leistung erzielt . Da der Test so naiv ist, glauben Sie den Zahlen nicht zu viel. Aber es scheint, dass der JIT-Compiler heutzutage sehr optimierten Code generiert. Dadurch konnte ich entscheiden, Vorlagen für meine Knoten-Apps der Verkettung vorzuziehen.
Als Referenz ist dies der Code, den ich verwendet habe:
'use strict' function strConcat(i) { return 'abc' + i + 'def' } function strTemplate(i) { return `abc${i}def` } function run(strategy) { let before = new Date().getTime() let len = 0 for ( let i = 0; i < 10000000; i+=1 ) { len += strategy(i).length } console.log(len + ' - ' + ((new Date().getTime()) - before) + 'ms') } console.log('strConcat') run(strConcat) console.log('strTemplate') run(strTemplate)
Und die Ausgabe war:
strConcat 128888890 - 1904ms strTemplate 128888890 - 1979ms
Ich habe immer
len
darauf geachtet, dass der Optimierer nicht die gesamte Schleife entfernt. Auf jeden Fall ist es immer noch ein sehr einfacher Test. Vielleicht kann jemand eine anspruchsvollere machen.quelle
Für einen einfachen Test mit Zufallszahlen als Zeichenfolge kommen sich beide in Chrome & FF so nahe
Testen in Chrome 58.0.3029 / Windows 10
Testen in Firefox 53.0.2 / Windows 10
Test hier bei jsperf
quelle
TL; DR
Die Verkettung ist schneller und gleichmäßiger in Bezug auf die Geschwindigkeit. Der Unterschied ist jedoch für 1 oder 2 Variablen sehr gering (unter 0,3 Sekunden für 100 Millionen Anrufe).
Bearbeiten
Nach dem zweiten Lauf scheint die Verkettung meistens die schnellere zu sein.
Daher wollte ich die Antwort von analog-nico erweitern, indem ich einen Test bereitstellte, der umfangreicher war und auch (ein bisschen) die Skalierbarkeit der beiden Funktionen untersuchte.
Code auf Pastebin
Ich entschied mich für vier Testfälle für jede Funktion, mit einer Variablen vorne, einer am Ende, einer in der Mitte und zwei Variablen in der Mitte. Die Grundeinstellung ist dieselbe. Ich verwende nur 100.000.000 Iterationen der Funktion und diese Iterationen werden 100 Mal ausgeführt. Ich habe dieselben Mechanismen verwendet, um eine Optimierung zu verhindern, nämlich die Summe der Längen der resultierenden Zeichenfolgen abzurufen und zu protokollieren. Ich habe auch die benötigte Zeit protokolliert (damit ich erraten kann, wie lange es dauern wird), sie aber auch in einem Array gespeichert.
Danach habe ich für jede Methode den Durchschnitt, das Minimum, das Maximum und die Standardabweichung berechnet.
Hier sind die Ergebnisse:
{ sum: { t: { start: 2072751, mid: 2338476, end: 2083695, double: 2950287 }, c: { start: 2086059, mid: 2345551, end: 2074732, double: 2922929 } }, avg: { t: { start: 20727.51, mid: 23384.76, end: 20836.95, double: 29502.87 }, c: { start: 20860.59, mid: 23455.51, end: 20747.32, double: 29229.29 } }, sd: { t: { start: 335.6251329981114, mid: 282.9490809315344, end: 286.2220947096852, double: 216.40844045461824 }, c: { start: 255.4803356424913, mid: 221.48744862858484, end: 238.98242111084238, double: 209.9309074433776 } }, min: { t: { start: 20490, mid: 23216, end: 20588, double: 29271 }, c: { start: 20660, mid: 23258, end: 20534, double: 28985 } }, max: { t: { start: 23279, mid: 25616, end: 22887, double: 30843 }, c: { start: 22603, mid: 25062, end: 22403, double: 30536 } } }
Werte in
t
-Objekten sind für Vorlagen, Werte inc
-Objekten sind für die Verkettung.start
bedeutet, dass sich die Variable am Anfang befindet, in der Mitte in der Mitte, am Ende am Ende und doppelt so viele Variablen.sum
ist die Summe aller 100 Läufe.avg
ist der durchschnittliche Lauf, was bedeutet, dass es istsum / 100
.sd
Hier ist der einfache Ausweg, Wikipedia (einfaches Englisch) .min
undmax
sind der minimale bzw. maximale Wert eines Laufs.Ergebnisse
Es scheint, dass Vorlagen für einzelne Variablen, die sich nicht am Ende einer Zeichenfolge befinden, schneller sind, wenn man bedenkt, dass der Durchschnitt niedriger und das Minimum niedriger ist. Wenn Sie eine Variable am Ende einer Zeichenfolge einfügen oder mehrere Variablen in Ihrer Zeichenfolge haben, ist die Verkettung schneller.
Obwohl sowohl das Minimum als auch der Durchschnitt der Vorlagen in Bezug auf die ersten beiden Bedingungen besser sind als ihre Gegenstücke zur Verkettung, ist die Standardabweichung durchweg schlechter. Der Unterschied scheint mit mehr Variablen zu schrumpfen (mehr Tests erforderlich).
Da die meisten Vorlagen wahrscheinlich nicht nur für eine Variable in einer Zeichenfolge verwendet werden, kann man sicher sagen, dass das Festhalten an der Verkettung zu einer besseren Leistung führt. Aber der Unterschied ist (zumindest für den Moment) sehr gering. Bei 100.000.000 (100 Millionen) Auswertungen mit zwei Variablen beträgt die Differenz lediglich 273,58 ms, etwa eine Viertelsekunde ...
Zweiter Lauf
Der zweite Lauf sieht etwas anders aus. Mit Ausnahme des Maximalwerts, der durchschnittlichen absoluten Abweichung und der Standardabweichung hat jede Messung bewiesen, dass die Verkettung schneller ist als Vorlagen.
Die drei genannten Messungen hatten niedrigere (also bessere) Werte für Vorlagen, wenn sich die Variable am Ende der Zeichenfolge befand oder wenn sich zwei Variablen in der Zeichenfolge befanden.
Hier sind die Ergebnisse:
{ "sum": { "t": { "start": 1785103, "mid": 1826679, "end": 1719594, "double": 2110823, "many": 4153368 }, "c": { "start": 1720260, "mid": 1799579, "end": 1716883, "double": 2097473, "many": 3836265 } }, "avg": { "t": { "start": 17851.03, "mid": 18266.79, "end": 17195.94, "double": 21108.23, "many": 41533.68 }, "c": { "start": 17202.6, "mid": 17995.79, "end": 17168.83, "double": 20974.73, "many": 38362.65 } }, "sd": { "t": { "start": 858.7857061572462, "mid": 886.0941856823124, "end": 786.5366719994689, "double": 905.5376950188214, "many": 1744.9005638144542 }, "c": { "start": 599.0468429096342, "mid": 719.1084521127534, "end": 935.9367719563112, "double": 991.5642274204934, "many": 1465.1116774840066 } }, "aad": { "t": { "start": 579.1207999999996, "mid": 576.5628000000003, "end": 526.8268, "double": 586.9651999999998, "many": 1135.9432000000002 }, "c": { "start": 467.96399999999966, "mid": 443.09220000000016, "end": 551.1318000000008, "double": 610.2321999999999, "many": 1020.1310000000003 } }, "min": { "t": { "start": 16932, "mid": 17238, "end": 16387, "double": 20016, "many": 39327 }, "c": { "start": 16477, "mid": 17137, "end": 16226, "double": 19863, "many": 36424 } }, "max": { "t": { "start": 23310, "mid": 24102, "end": 21258, "double": 26883, "many": 49103 }, "c": { "start": 19328, "mid": 23203, "end": 22859, "double": 26875, "many": 44352 } }, "median": { "t": { "start": 17571, "mid": 18062, "end": 16974, "double": 20874, "many": 41171.5 }, "c": { "start": 16893.5, "mid": 18213, "end": 17016.5, "double": 20771, "many": 38849 } } }
Der Code ist hier
quelle
absolute average mean
und diemedian
. Außerdem wird die Laufzeit mit 10 zu ersetzenden Variablen bewertet.Ich denke, dass der obige Benchmark nicht nützlich ist. Das Ergebnis der Interpolation oder Verkettung wurde nicht verwendet. Ja, die Verkettung ist ziemlich schnell, da dort keine Zeichenfolge und die Ergebniszeichenfolge nur Links zu den übergeordneten Zeichenfolgen enthalten. Wenn Sie jedoch die Ergebniszeichenfolge ausprobieren oder mit einer anderen vergleichen, wird die Zeichenfolge in eine ebene Zeichenfolge serialisiert, und ja, es wird einige Zeit dauern. Daher könnte die Interpolation für die CPU- und Speichernutzung effektiver sein als die Verkettung in realen Fällen.
quelle