JavaScript String Concatenation Speed Test
One performance recommendation I’ve seen was about concatenating really long strings. Unless you are using bits of JavaScript to prettify your pages, AJAX+DHTML web apps use tons of these long strings as templates, just as a server-side web framework would do. Unfortunately, JavaScript has no support for multiline strings, so we end up using multiple single-line strings, and concatenating them one way or the other. As these stings are very long, and abundant, it makes sense to make string concatenation as fast as possible.
String concatenation techniques
There are four methods for string concatenation that I know of.
Variable overloading
The first method is one that I’ve seen a lot in other languages:
var longStr = 'This is a very long string.<br>';
longStr += 'It contains many lines of text<br>';
longStr += 'concatednated and presented<br>';
longStr += 'to you on silver platter.<br>';
longStr += '<br>';
You just keep adding new strings to the existing ones.
Classic concatenation
By classic concatenation, I mean this:
var longStr = 'This is a very long string.<br>' +
'It contains many lines of text<br>' +
'concatednated and presented<br>' +
'to you on silver platter.<br>' +
'<br>';
A big advantage of this method is that it’s much more readable than the previous one.
concat method
JavaScript’s String object has a concat method, which concatenates strings with the string object on which it is called:
var longStr = 'This is a <em>very</em> long string.<br>'.concat(
'It contains many lines of text<br>',
'concatednated and presented<br>',
'to you on silver platter.<br>',
'<br>');
I don’t like this method because it is confusing. It singles out the first part of the string from the rest. A little bit better variaton could be:
var longStr = ''.concat(
'This is a <em>very</em> long string.<br>',
'It contains many lines of text<br>',
'concatednated and presented<br>',
'to you on silver platter.<br>',
'<br>');
The first string, to which the others are concatenated is an empty string. I imagine it would be a tad bit slower that way, but it’s more readable.
Array join
At last, but not least, a method that is also quite common in other languages (though probably not as common as the previous two):
var longStr = ['This is a very long string.<br>',
'It contains many lines of text<br>',
'concatednated and presented<br>',
'to you on silver platter.<br>',
'<br>'].join('');
The Array.prototype.join method concatenates the elements in an array, and outputs a string. One advantage of this method is that you can specify separators. The above example can be rewritten like so:
var longStr = ['This is a very long string.',
'It contains many lines of text',
'concatednated and presented',
'to you on silver platter.',
'<br>'].join('<br>');
It yields the exact same string as the first array join example, if you must know.
UPDATE: You can start off with an array that contains just the first string segment, and use the push method to add the others one by one. It doesn’t affect the performance by much.
The test
As with the Array loop speed test, I’ve prepared a few tests on Jsfiddle. You can profile the results iframe (lower right quadrant) and check the results yourself.
One note before you start analyzing the result. You may notice that the results are ordered more or less consistently, with test1() and test3() being the fastest. However, this may be misleading. Depending on how you order the tests on execution, test2() can be as fast as test3(), and when test2() is fast, test3() is slow. The rule is that the last array join test to run wins. test4(), the concat method, performs slower than classic concatenation (twice as slow, actually).
UPDATE: I’ve modified the test code to include a variant of the array join method that uses push to build the array. Surprisingly, it doesn’t affect the test results much, with test5() using this method being just as fast as test3() which uses the normal array join method, and sometimes performing even better.
I’ve written a modified test set to show you something interesting. In the modified set, test4() is exactly the same as test3(), and it is also the fastest, but not by much (and not always). test3() and test4() have about the same times. It seems that array join method gets some boost after the first such join is executed, and then maintains consistently high performance on subsequent executions. I’m not sure how to interpret this, but I find this to be somewhat unreliable.
Overall, test1(), classic concatenation, seems to be consistently performant in my tests, and I definitely choose that method over the other methods.
Another interesting point is that for templates, you generally don’t want to use DOM manipulation methods from your favorite JavaScript library. Those execute a lot of code, and are fairly slow as a result. They also inject a lot of invisible DOM elements into the vacuum outside the DOM tree, so they can be a bit messy. It’s best to use methods like element.innerHTML to insert a string (jQuery’s equivalent is $(selector).html()). Just my opinion anyway.
For comparison, though, I’ve included a crude test using document.write (yes, I know, hardly a realistic scenario) in another set of string concatenation tests, and it turns out that this method is still faster than variable overloading.
To conclude, stay away from variable overloading. They’re evil. And slow as hell. For the same reasons, don’t abuse DOM manipulation functionality to build what can be accomplished by string templates. Use classic concatenation, or array join if you’ll be doing a lot of those in a sequence. Both methods are very fast, compared to variable overloading (maybe by factor of 50 to 70).




