¿La generación de código HTML se ejecuta considerablemente más rápido en los navegadores modernos cuando se usa concatenación de cadenas o literales de plantilla en ES6?
Por ejemplo:
Concatenación de cadenas
"<body>"+
"<article>"+
"<time datetime='" + date.toISOString() +"'>"+ date +"</time>"+
"</article>"+
"</body>"
Plantilla literal
`<body>
<article>
<time datetime='${ date.toISOString() }'>${ date }</time>
</article>
</body>`
javascript
string
performance
templates
ecmascript-6
hurrymaplelad
fuente
fuente
Respuestas:
Por el momento, parece que la concatenación de cadenas es más rápida: http://jsperf.com/es6-string-literals-vs-string-concatenation
Probé que se ejecutó en Chrome 43.0.2334.0 canary (64 bits), que usa V8 4.3.31, con la
#enable-javascript-harmony
bandera habilitada.Como referencia, la última versión de Node.js (0.12.0 en el momento de escribir este artículo) usa V8 3.28.73: https://raw.githubusercontent.com/joyent/node/master/ChangeLog
Estoy seguro de que todavía no se han aplicado todas las posibles optimizaciones de rendimiento que podrían aplicarse, por lo que sería razonable esperar que el rendimiento mejore a medida que ES6 se acerca a la finalización y estas características se migran a la rama estable.
Editar: Gracias por los comentarios @ user1329482, @ icl7126, Nicolai Borisik y FesterCluck. Ahora que han pasado aproximadamente 2 años desde que se hizo esta pregunta, la compatibilidad con el navegador ES6 ha aumentado enormemente y se ha realizado una buena cantidad de optimización del rendimiento. Aquí hay algunas actualizaciones .
Editar: (febrero de 2020) Resultado actualizado de Chrome basado en comentarios de @ JorgeFuentesGonzález y posterior confirmación .
En Chrome (a partir de 59.0.3035), los literales de cadena ES6 son más rápidos :
Actualización: en Chrome (a partir de 79.0.3945), la concatenación de cadenas es más rápida ... Ver comentarios.
En Firefox (a partir de 57.0.0), los literales de cadena ES6 son más rápidos :
En Safari (a partir de 11.0.2), depende:
Cuando se usa una cadena encasillada, los literales de cadena ES6 son más rápidos . Sin embargo, cuando se llama a una función desde el literal, la concatenación de cadenas es más rápida en este ejemplo.
Si realmente desea profundizar y necesita exprimir hasta la última gota de rendimiento de Safari, sugeriría configurar pruebas que vean si / cómo se escribieron incorrectamente las variables y múltiples referencias dentro de un rendimiento de efecto literal.
fuente
Hice una prueba ingenua en node.js v6.0.0 y obtuve casi el mismo rendimiento . Dado que la prueba es tan ingenua, no crea demasiado en los números. Pero parece que el compilador JIT genera código muy optimizado hoy en día. Esto me permitió decidir preferir las plantillas a la concatenación para mis aplicaciones de nodo.
Como referencia, este es el código que utilicé:
'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)
Y el resultado fue:
strConcat 128888890 - 1904ms strTemplate 128888890 - 1979ms
Solía
len
asegurarme absolutamente de que el optimizador no optimiza todo el ciclo. De todos modos, sigue siendo una prueba muy sencilla. Quizás alguien pueda hacer uno más sofisticado.fuente
Para una prueba simple con números aleatorios como cadena, ambos se acercan tanto en Chrome y FF
Pruebas en Chrome 58.0.3029 / Windows 10
Pruebas en Firefox 53.0.2 / Windows 10
Prueba aquí en jsperf
fuente
TL; DR
La concatenación es más rápida y consistente con respecto a su velocidad. Pero la diferencia es muy pequeña para 1 o 2 variables (por debajo de 0,3 segundos para 100 millones de llamadas).
Editar
Después de la segunda ejecución, parece que la concatenación es principalmente la más rápida de las dos.
Entonces, quería expandir la respuesta de analog-nico proporcionando una prueba que era más extensa y también miraba (un poco) la escalabilidad de las dos funciones.
Código en pastebin
Decidí usar cuatro casos de prueba para cada función, con una variable al frente, una al final, una en el medio y dos variables en el medio. La configuración básica es la misma. Solo estoy usando 100,000,000 iteraciones de la función y estas iteraciones se ejecutan 100 veces. Usé los mismos mecanismos para evitar la optimización, es decir, obtener la suma de las longitudes de las cadenas resultantes y registrarla. También registré el tiempo necesario (para adivinar cuánto tiempo tomará) pero también lo guardé en una matriz.
Posteriormente, calculé la desviación promedio, mínima, máxima y estándar para cada método.
Aquí están los resultados:
{ 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 } } }
los valores en
t
-objects son para plantillas, los valores enc
-objects son para concatenación.start
significa que la variable está al principio, mid que está en el medio, end que está al final y double que hay dos variables.sum
es la suma de las 100 carreras.avg
es la carrera promedio, lo que significa que lo essum / 100
.sd
Aquí está la salida fácil, wikipedia (inglés simple) .min
ymax
son el valor mínimo y máximo de una ejecución, respectivamente.Resultados
Parece que las plantillas son más rápidas para las variables individuales que no se encuentran al final de una cadena, considerando que el promedio es menor y el mínimo es menor. Si coloca una variable al final de una cadena o tiene varias variables en su cadena, la concatenación es más rápida.
Aunque el mínimo y el promedio de las plantillas son mejores que sus contrapartes de concatenación con respecto a las dos primeras condiciones, la desviación estándar es consistentemente peor. La diferencia parece reducirse con más variables (se necesitan más pruebas).
Dado que la mayoría de las plantillas probablemente no se utilizarán para una sola variable en una cadena, conviene decir que ceñirse a la concatenación produce un mejor rendimiento. Pero la diferencia es (al menos por ahora) muy marginal. En 100,000,000 (100 millones) evaluaciones con dos variables, la diferencia es simplemente 273,58 ms, aproximadamente un cuarto de segundo ...
Segunda ejecución
La segunda ejecución se ve algo diferente. Excepto por el valor máximo, la desviación absoluta promedio y la desviación estándar, cada medición demostró que la concatenación es más rápida que las plantillas.
Las tres medidas mencionadas tenían valores más bajos (por lo tanto mejores) para las plantillas cuando la variable estaba al final de la cadena o cuando había dos variables en la cadena.
Aquí están los resultados:
{ "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 } } }
El codigo esta aqui
fuente
absolute average mean
y elmedian
. También compara el tiempo de ejecución con 10 variables para reemplazar.Creo que el punto de referencia anterior no es útil. No se ha utilizado el resultado de la interpolación o la concatenación. Así que sí, la concatenación es bastante rápida, porque ninguna cadena de copia allí y la cadena de resultado solo tienen enlaces a las cadenas principales. Pero si prueba la cadena de resultados o la compara con otra, la cadena se serializará en la cadena plana y, sí, llevará algún tiempo. Por lo tanto, la interpolación podría ser más efectiva para el uso de la CPU y la memoria que la concatenación en casos reales.
fuente