Are ES6 template literals faster than string concatenation?
Solution 1
It seems for the moment string concatenation is faster: 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
I tested was run on Chrome 43.0.2334.0 canary (64-bit), which is using V8 4.3.31, with the #enable-javascript-harmony
flag enabled.
For reference, the latest version on Node.js (0.12.0 at the time of writing) is using V8 3.28.73: https://raw.githubusercontent.com/joyent/node/master/ChangeLog
I'm sure all the possible performance optimizations that could be applied have not been applied yet, so it would be reasonable to expect performance to get better as ES6 gets closer to finalization and these features get migrated to the stable branch.
Edit: Thanks for the comments @user1329482, @icl7126, Nicolai Borisik, and FesterCluck. Now that about 2 years have passed since this question was asked, ES6 browser support has greatly increased, and a good amount of performance optimization has taken place. Here are some updates.
Edit: (February 2020) Updated Chrome result based on @JorgeFuentesGonzález comments and subsequent confirmation.
In Chrome (as of 59.0.3035), ES6 string literals are faster:
ES6 with variable 48,161,401 ±1.07% fastest
String concatenation with variable 27,046,298 ±0.48% 44% slower
ES6 with function 820,441 ±1.10% 98% slower
String concatenation with function 807,088 ±1.08% 98% slower
Update: In Chrome (as of 79.0.3945), String concatenation is faster... See comments.
In Firefox (as of 57.0.0), ES6 string literals are faster:
ES6 with variable 1,924,610,984 ±0.50% fastest
String concatenation with variable 1,876,993,458 ±0.79% 3% slower
ES6 with function 539,762 ±5.04% 100% slower
String concatenation with function 546,030 ±5.88% 100% slower
In Safari (as of 11.0.2), it depends:
ES6 with variable 1,382,752,744 ±0.71% fastest
String concatenation with variable 1,355,512,037 ±0.70% 2% slower
ES6 with function 876,516 ±1.01% 100% slower
String concatenation with function 883,370 ±0.79% 100% slower
When using a typecast string, ES6 string literals are faster. However, when calling a function from the literal, string concatenation is faster in this example.
If you really want to go deep and need to squeeze every drop of performance out of Safari, I would suggest setting up tests that see if/how incorrectly typed variables and multiple references within a literal effect performance.
Solution 2
I did a naive test on node.js v6.0.0 and got nearly the same performance. Since the test is so naive, don't believe the numbers too much. But it seems the JIT compiler generates very optimised code nowadays. This let me decide to prefer templates over concatenation for my node apps.
For reference this is the code I used:
'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)
And the output was:
strConcat
128888890 - 1904ms
strTemplate
128888890 - 1979ms
I used len
to absolutely make sure that the optimizer doesn't optimize the whole loop away. Anyway, it is still a very simple test. Maybe someone can make a more sophisticated one.
Solution 3
TL;DR
Concatenation is faster and more consistent regarding its speed. But the difference is very little for 1 or 2 variables (below .3 seconds for 100 million calls).
Edit
After the second run it seems that concatenation is mostly the faster of the two.
So, I wanted to expand analog-nico's answer by providing a test that was more extensive and also looked (a bit) into scalability of the two functions.
I decided to use four test cases for each function, having a variable in the front, one at the end, one in the middle and two variables in the middle. The basic setup is the same. I'm just using 100,000,000 iterations of the function and these iterations are run 100 times. I used the same mechanisms to prevent optimization, namely getting the sum of the lengths of the resulting strings and logging it. I also logged the time needed (for me to guess how long it'll take) but also saved it into an array.
Afterwards, I calculated the average, minimum, maximum, and standard deviation for each method.
Here are the results:
{
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
}
}
}
values in t
-objects are for templates, values in c
-objects are for concatenation. start
means that the variable is at the beginning, mid that it is in the middle, end that it is at the end and double that there are two variables. sum
is the sum of all 100 runs. avg
is the average run, meaning it is sum / 100
. sd
Here is the easy way out, wikipedia (simple english). min
and max
are the minimum and maximum value of a run respectively.
Results
It seems like templates are faster for single variables that are not located at the end of a string, considering that the average is lower and the minimum is lower. If you put a variable at the end of a string or have multiple variables in your string, concatenation is faster.
Although the minimum as well as the average of templates is better than their concatenation counterparts regarding the first two conditions, the standard deviation is consistently worse. The difference seems to shrink with more variables (more tests needed).
Since most templates won't probably be used for only one variable in a string, it is save to say that sticking to concatenation yields a better performance. But the difference is (at least for now) very marginally. At 100,000,000 (100 million) evaluations with two variables, the difference are merely 273,58 ms, about a quarter second...
Second Run
The second run looks somewhat different. Except for the maximum value, average absolute deviation, and standard deviation, every measurement proofed that concatenation is faster than templates.
The three mentioned measurements had lower (thus better) values for templates when the variable was at the end of the string or when there were two variables in the string.
Here are the results:
{
"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
}
}
}
Solution 4
For a simple test with random numbers as string, both are coming so close in Chrome & FF
Testing in Chrome 58.0.3029 / Windows 10
String literals 2,996,883 ±2.36% fastest
Operator (+) 3,054,078 ±2.01% fastest
Concat function 2,659,391 ±2.35% 13% slower
Testing in Firefox 53.0.2 / Windows 10
String literals 1,923,835 ±1.52% fastest
Operator (+) 1,948,503 ±1.13% fastest
Concat function 1,810,857 ±1.81% 8% slower
hurrymaplelad
Updated on July 06, 2020Comments
-
hurrymaplelad almost 4 years
Does HTML code generation run measurably faster in modern browsers when using string concatenation or template literals in ES6?
For example:
String concatenation
"<body>"+ "<article>"+ "<time datetime='" + date.toISOString() +"'>"+ date +"</time>"+ "</article>"+ "</body>"
Template literal
`<body> <article> <time datetime='${ date.toISOString() }'>${ date }</time> </article> </body>`
-
rattray over 7 yearsI ran a similar benchmark and got a similar result. My benchmark included more strings, some of which were longer. Interpolation performs slightly better than concatenation.
-
icl7126 over 7 yearsFirefox 50 64bit - ES6 has same speed as concatenation 1,423,816,207 Ops/s.
-
Nikolai Borisik over 7 yearsSafari 9.0 ES6 interpolations faster than concatenation about 34% Chrome 55 still ES6 interpolations much slower Firefox 50 the same speed
-
Armin over 6 yearsI'm currently running a new version of my test script. It includes the
absolute average mean
and themedian
. It also benchmarks the runtime with 10 variables to replace. -
FesterCluck over 6 yearsTemplate strings are now an order of magnitude faster than string concatenation. See version 14 of the given jsperf, it is the most accurate & unbiased one can technically get while retaining feature aspects. Version 17 is least biased but unrealistic.
-
Jorge Fuentes González over 4 yearsThe jsperf link you passed, in "Revision 1" string literals are still slower than string concatenation under latest Chrome: u.teknik.io/nPmY8.png
-
Andrew Odri over 4 years@JorgeFuentesGonzález Yup, just tested on Chrome 79.0.3945 and got a similar result to you... Really interesting, I'll update the post :)
-
Jorge Fuentes González over 4 yearsThe jsperf result file got deleted. Uploaded this one without expiration: u.teknik.io/02OVr.png
-
Artur Müller Romanov almost 3 years@AndrewOdri Just wanted to point out how much you have helped the community with this post and thank you in the name of all of us :-)
-
Andrew Odri almost 3 yearsThanks @ArturMüllerRomanov!!! It's really too bad jsperf folded though... It'll be a lot harder to collect crowdsourced data like this for future tests
-
zwcloud almost 2 years@JorgeFuentesGonzález expired
-
Jorge Fuentes González almost 2 years@zwcloud yep, teknik somehow changed. I've changed img hosting server since a couple months.