F1 Rivals
The most erroneous stories are those we think we know best - and therefore never scrutinize or question.
- Stephen Jay Gould (1941 - 2002)

DOM vs String concatenation vs Array join

In a bit of a follow up to my previous post about long running JavaScript tasks I want to explore element creation using three different techniques. The “right” way to create elements is to use the document.createElement method. But sometimes the “right” way is simply not the best way.

I was working on a project recently where we were generating SVG dynamically. Specifically we had an array of points which needed to be converted into a d attribute for a path element. The code would generate an “M x0 y0″ for the first point and then “L xn yn” for each subsequent point (for n > 0, n < number of points). It was essentially building one long string using the standard string concatenation operator (+). The project is an Intranet system and targets IE exclusively. And IE was taking about 6 seconds to buildup a string of 1200 points.

My first thought was to use the Task class from my previous post so that at least the user is aware that something is happening and that their damned browser hadn’t crashed again. I gave the user some feedback every 100 points or so, and that was fine. I then had a look at the code that generates the string and decided to take a page from my C# programming book and implement a StringBuilder.

Well, not quite. But the JavaScript array suffices as a perfectly good string builder. Array.push replaces StringBuilder.Append and Array.join replaces StringBuilder.ToString.

And what does this have to do with the DOM? Well, nothing. But elsewhere in the same project we were building a whole bunch of select elements using the DOM and guess what: IE is slow at that too. Let me explain by example:

var select = document.createElement("select");
for(var i = 0; i < 10000; ++i) {
    var opt = select.appendChild(document.createElement("option"));
    opt.text = i;
    opt.value = i;
}
$("output").appendChild(select);

This code creates a select element and adds options for values from 0 to 9999 to it. In a quick test on my box, IE took 129609 ms to run this code! Just over 2 minutes! (The test was run on IE7)

Okay, so what about string concatenation? If we change the code to:

var html = "<select>";
for(var i = 0; i < 10000; ++i) {
    html += "<option value='" + i + "'>" + i + "</option>";
}
html += "</select>";
$("output").update(html);

IE took just 4937 ms to run this. That’s a one gazzilion percent improvement. But wait, we can do better still:

var stringBuilder = [];
stringBuilder.push("<select>");
for(var i = 0; i < 10000; ++i) {
    stringBuilder.push("<option value='" + i + "'>" + i + "</option>");
}
stringBuilder.push("</select>");
$("output").update(stringBuilder.join());

IE took only 312 ms to run that. My calculator started smoking when I tried to calculate the improvement.

So then what about the other major browsers? Let me enumerate the results (please note this was not a clinical test with reboots in between, on a new install or even ensuring that nothing else was running in the background. In fact to reproduce these results you will need WinAmp playing, Pidgin running connected to 2 IRC channels and chatting to a bunch of folks, all the tested browsers open at the same time… but not running the test at the same time).

IE7: DOM 129609 ms, String 4937 ms, Array 312 ms
Firefox 2: DOM 1360 ms, String 609 ms, Array 593 ms
Opera 9: DOM 1578 ms, String 516 ms, Array 781 ms
Safari 3 Beta: Dom 500 ms, String 344 ms, Array 468 ms

So Safari and Opera are marginally faster using the string than using the array and all three have a DOM implementation that just makes IE’s look downright silly. (Firefox is quite inconsistent, multiple tests show wildly varying results that may have something to do with having 7 tabs open). I would without hesitation, recommend using the Array method in all browsers at this time. The saving of the string implementation in Opera and Safari is not worth the extra complexity of writing the browser testing code and implementing 2 methods.

If you’d like to run the test yourself, I have put my hastily hacked together test suite here.

[?]
Share This

Posted by Marc on Nov 07 2007 under Development




One Response to “DOM vs String concatenation vs Array join”

  1. Andre Says:

    Any theories on why the IE DOM implementation is so slow?

Leave a Comment


ZATopSites - top sites, top web, south africa Afrigator