大きな文字列が猛烈に遅い

http://www.geocities.jp/pxu02524/personal/prime.htm


Ajaxで、
例えばcsvファイルをXMLHttpRequestで読んで、
それをテーブルにして表示する、
ということを考える。
こんな感じ:


var data;

function readData() {
...
reqPrime.onreadystatechange = function() {
if(reqPrime.readyState == 4) {
data = reqPrime.responseText;
...
}

function test1() {
var str = "<table>";
var lines = data.split("\n");
for(var i = 0; i < lines.length; i++) {
str += "<tr><td>";
str += lines[i].replace(/,/g, "</td><td>");
str += "</td></tr>";
}
str += "</table>";

document.getElementById("tblPrime").innerHTML = str;
}

上のリンク先のページで、
test1のボタンを押したとき非常に遅い。
どうせレンダリングに時間がかかっているのだろうと思って時間を計ったのがそのボタンの下の二つの数字。
上がstrを作るのにかかった時間、
下がinnerHTMLに代入している時間(たぶんparseとレンダリングの時間)。


実は、圧倒的にstrを作るのにかかった時間が大きい。
これでも、replaceを使って時間短縮したつもりだったのに。
正規表現なんか使っているから遅いのだろうか。


一工夫してみた。


for(var i = 0; i < lines.length; i++) {
str += "<tr><td>"
+ lines[i].replace(/,/g, "</td><td>")
+ "</td></tr>";
}

3回に分けて足していたのを一度に足してみただけだが、
これでほぼ1/3になっている。
結合の回数が1/3になったから速くなったというだけ。


そんなに大きな文字列の結合は遅いのか。


それを避けるために配列を使ってみた。


var str = [ ];
for(var i = 0; i < lines.length; i++) {
str[i] = "<tr><td>"
+ lines[i].replace(/,/g, "</td><td>")
+ "</td></tr>";
}

document.getElementById("tblPrime").innerHTML
= "<table>" + str.join("") + "</table>";

小さな文字列に小分けして、
あとからjoinメソッドで結合する。
これで最初の1〜2%の時間になった。


配列(Arrayオブジェクト)はそんなに遅くない、
というか大きなStringが圧倒的に遅いのか。


大きなStringの結合は避けるべし。


追記:
上はIEでの実験だが、
Firefoxで試すとやるたびに結果が変わって
よく分からない。
平均するとtest1,2,3であまり変わらないのか?
しかし、test3で書くのが正しいことに変わりはない。