String performance in Internet Explorer

By crisp on Saturday 9 December 2006 02:58
Categories: Browsers, Javascript, Views: 15.164

This was meant to be a short item in the "Having fun with IE"-series but when I was doing some research and testing I found a lot of interesting things so this subject really deserves it's own title.

It started with some testing I did for the infamous IE+JavaScript Performance Recommendations-series with regards to Microsofts' tip to use an array to do string-concatenation. Now string handling in IE's JScript is known to be painstakingly slow and array functions are known to be faster in IE so the tip has some worth but calling it a 'recommendation' is plain stupid: it's a workaround for an IE-specific implementation problem and as such should only be applied to IE and than only when you have an actual need to do so (Beware of premature optimization).

Now in my preliminary testing of the speed of plain concatenation versus the Array.join() method on my home-pc (an AMD XP2000+ with 512MB ram running win2K) in IE6 I found that - even when I optimized the filling of the array by using array[array.length] = string instead of using the slower push() method - the Array.join() method was not particularly faster when working with strings up to 60-70K characters.

I created two benchmarks scripts for this test. Both scripts create large strings, first a string with 1000 characters, than one with 2000 characters and so on up untill a string with 100.000 characters. For each step it outputs the total time needed to create the string so I could copy-paste the results into a spreadsheet to create a graph.
The first script uses normal string-concatenation using the + operator, the second script uses the Array.join() technique. For the graph I took the average times of 3 complete runs to flatten out any anomalies and it resulted in this:

Here you can see that both methods are fairly linear in performance, but that the string concatenation method suddenly starts to become much slower when creating strings bigger than 70.000 characters wereas the array-method remains lineair. This would mean that Microsofts' tip is only valid when handling very large strings in IE.
Also note the benchmark times; doing a complete run on my (not so fast) pc took a whopping 5 minutes for benchmark 1 and still 2.5 minutes for benchmark 2. For comparision: Firefox 2.0 did benchmark 1 in 12 seconds and benchmark 2 in 20 seconds and Opera 9 did benchmark 1 in 3.5 seconds and benchmark 2 in 7.5 seconds - and yes, obviously normal string concatenation is better in those browsers than using Array.join().

I didn't leave it at that; I decided to test it also in IE7 to see if there were any improvements. For that I used my work-pc which is a P4 3.2Ghz with 2.5GB ram running winXP. Now comes the interesting part; this is the same graph as above for IE7:

Now disregarding the timings (it is a faster PC) the following things can be noticed: normal concatenation doesn't seem to be lineair at all anymore, not even up to the 70K point, but polynomial all the way. On the other hand array performance is still fairly lineair and 5x better than in IE6 which can be seen in this graph including IE7, IE6, Firefox 2.0 and Opera9:

For good measure here are the total results of both benchmarks by browser:

It's obvious that array performance has been much improved in IE7, but string performance hasn't. It seems to be platform (or OS?) related how bad string performance actually is compared to array performance. In IE7 filling an array and joining the parts together is even faster than in Firefox (although normal concatenation in Firefox is still slightly faster), so there is even more incentive to use the Array.join() technique for IE7.

But then why doesn't IE implement String as a character-array? All other browsers also support alert('foo'[2])...

Trying with a StringBuffer

The cousin of javascript allows you to work with stringbuffers, so I decided to create a simple StringBuffer implementation in javascript:

function StringBuffer()
    this.str = [];
StringBuffer.prototype =
    append: function(str)
        this.str[this.str.length] = str;
    flush: function()
        return this.str.join('');

But then IE fails miserably again; the array-performance improvements in IE7 just don't make up for the poor object-performance in IE (testscript):


Microsoft surely did a good job improving array-handling performance in IE7 (although it remains to be seen if that counts for all array-related methods), but string-performance and object-performance are still below standard. If your application suffers from the poor string-handling performance in IE you might consider using the Array.join() method but implementing that in a non-obtrusive (only targetted at IE) way seems to be nearly impossible, so you probably have to settle for a trade-off of less performance (but still better or almost as good as in IE) in other browsers...

Volgende: Internet Explorer and cacheing: beware of the Vary 12-'06 Internet Explorer and cacheing: beware of the Vary
Volgende: The useless javascript: pseudo-protocol 12-'06 The useless javascript: pseudo-protocol


Comments are closed