¿Los literales de templates ES6 son más rápidos que la concatenación de cadenas?

¿Alguien ha hecho puntos de reference? Tengo curiosidad por saber si el código de generación HTML es más rápido con la concatenación de cadenas o con los literales de las templates en el nodo y en los browseres modernos.

Por ejemplo:

Concatenación de cadenas

"<body>"+ "<article>"+ "<time datetime='" + date.toISOString() +"'>"+ date +"</time>"+ "</article>"+ "</body>" 

Literal de plantilla

 `<body> <article> <time datetime='${ date.toISOString() }'>${ date }</time> </article> </body>` 

Parece que por el momento la concatenación de cadenas es más rápida : http://jsperf.com/es6-string-literals-vs-string-concatenation

 ES6 with variable 19,992,512 ±5.21% 78% slower String concatenation with variable 89,791,408 ±2.15% fastest ES6 with function 461,358 ±3.12% 99% slower String concatenation with function 503,255 ±1.77% 99% slower 

Probé se ejecutó en Chrome 43.0.2334.0 canary (64 bits), que está utilizando V8 4.3.31, con el indicador #enable-javascript-harmony activado.

Como reference, la última versión en Node.js (0.12.0 en el momento de la escritura) está utilizando V8 3.28.73: https://raw.githubusercontent.com/joyent/node/master/ChangeLog

Estoy seguro de que no se han aplicado todas las posibles optimizaciones de performance que podrían aplicarse, por lo que sería razonable esperar que el performance mejore a medida que ES6 se acerca a la finalización y estas características se migran a la twig estable.

Hice una testing ingenua en node.js v6.0.0 y obtuve casi el mismo performance . Dado que la testing es tan ingenua, no creas demasiado los numbers. Pero parece que el comstackdor JIT genera un código muy optimizado hoy en día. Esto me permite decidir si prefiero las templates sobre la concatenación para las aplicaciones de mi nodo.

Como reference, 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 la salida fue:

 strConcat 128888890 - 1904ms strTemplate 128888890 - 1979ms 

len para asegurarme absolutamente de que el optimizador no optimiza todo el bucle. De todos modos, sigue siendo una testing muy simple. Tal vez alguien puede hacer uno más sofisticado.

Para una testing simple con numbers aleatorios como cadena, ambos están llegando muy cerca en Chrome y FF

Prueba en Chrome 58.0.3029 / Windows 10

Cadena literales 2,996,883 ± 2,36% más rápido

Operador (+) 3.054.078 ± 2.01% más rápido

Función Concat 2.659.391 ± 2.35% 13% más lenta

Pruebas en Firefox 53.0.2 / Windows 10

Cadena literales 1.923.835 ± 1.52% más rápido

Operador (+) 1.948.503 ± 1.13% más rápido

Función Concat 1,810,857 ± 1,81% 8% más lento

Prueba aquí en jsperf

TL; DR

La concatenación es más rápida y más consistente con respecto a su velocidad. Pero la diferencia es muy pequeña para 1 o 2 variables (por debajo de .3 segundos para 100 millones de llamadas).

Editar

Después de la segunda ejecución, parece que la concatenación es, en su mayoría, la más rápida de las dos.


Por lo tanto, quería expandir la respuesta de analog-nico al proporcionar una testing que era más extensa y también parecía (un poco) en la escalabilidad de las dos funciones.

Código en pastebin

Decidí usar cuatro casos de testing para cada function, teniendo una variable en el frente, una al final, una en el medio y dos variables en el medio. La configuration básica es la misma. Solo uso 100,000,000 iteraciones de la function y estas iteraciones se ejecutan 100 veces. Usé los mismos mecanismos para evitar la optimization, es decir, get la sum de las longitudes de las cadenas resultantes y registrarla. También registré el time necesario (para que adivine cuánto time tomará) pero también lo guardé en una matriz.

Después, calculé el promedio, el mínimo, el máximo y la desviación 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 templates, los valores en c -objects son para concatenación. start significa que la variable está en el comienzo, que está en el medio, que está al final y que el doble que hay dos variables. sum es la sum de las 100 carreras. avg es la ejecución promedio, lo que significa que es sum / 100 . sd Aquí está la salida fácil, wikipedia (inglés simple) . min y max son el valor mínimo y máximo de una carrera, respectivamente.

Resultados

Parece que las templates son más rápidas para las variables individuales que no se encuentran al final de una cadena, considerando que el promedio es más bajo y el mínimo es más bajo. Si coloca una variable al final de una cadena o tiene múltiples variables en su cadena, la concatenación es más rápida.

Aunque tanto el mínimo como el promedio de templates es mejor que sus equivalentes de concatenación con respecto a las dos primeras condiciones, la desviación estándar es siempre peor. La diferencia parece networkingucirse con más variables (se necesitan más testings).

Dado que la mayoría de las templates probablemente no se utilizarán para una sola variable en una cadena, es fácil decir que al pegar en la concatenación se obtiene un mejor performance. Pero la diferencia es (al less por ahora) muy marginal. En 100,000,000 (100 millones) de evaluaciones con dos variables, la diferencia es meramente 273,58 ms, aproximadamente un cuarto de segundo …


Segunda corrida

La segunda ejecución se ve algo diferente. Excepto por el valor máximo, la desviación absoluta media y la desviación estándar, todas las medidas a testing de que la concatenación es más rápida que las templates.

Las tres medidas mencionadas tenían valores más bajos (por lo tanto, mejores) para las templates 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 código esta aqui