« JavaScript第5版読書会#1参加者の参加報告の一覧 | メイン | LiveCoding#5で披露してしまった「任意のコードを実行するBookmarklet」について »

配列の初期値を指定する方法の処理速度検証

JavaScript第5版読書会#1で披露した「配列の初期値を指定する方法」のその後の展開。『「配列の初期値を指定する方法」の「一文字の文字列しか指定できない制限」の打破を試みる』のエントリーを見たmurky-satyrさんが制限を突破した。murky-satyrさんの処理をもとに新規に作成した関数の処理速度がどれほどか検証してみる。検証はFirefox for Macで行った。尚、検証中に明らかに処理が遅くなることがあったが、GCの動作中と思われるのでこの場合はもう一度測定した。
まず、処理の処理速度の比較を、次の3つの処理に対して行った。
process1
//空の配列を生成=>メソッドにより拡張
function arrayFill(num,str){
    var rtn=[];
    var i;
    for(i=0;i<num;i++){
        rtn.push(str);
    }
    return rtn;
}
process2
//空の配列を生成=>範囲外の添字を指定し拡張
function arrayFill(num,str){
    var rtn=[];
    var i;
    for(i=0;i<num;i++){
        rtn[i]=str;
    }
    return rtn;
}
process3
//サイズ指定した配列を生成=>範囲内の添字を指定し拡張
function arrayFill(num,str){
    var rtn=new Array(num);
    var i;
    for(i=0;i<num;i++){
        rtn[i]=str;
    }
    return rtn;
}
検証方法は以下の通り。
test1
//10000回-10個-10文字
//処理回数が多い
var d=new Date();
for(var j=0;j<10000;j++){
   arrayFill(10,"1234567890");
}
(new Date())-d;
test2
//10回-10000個-10文字
//要素数が多い
var d=new Date();
for(var j=0;j<10;j++){
   arrayFill(10000,"1234567890");
}
(new Date())-d;
test3
//10回-10000個-10000文字
//要素数と文字数が多い
//(文字数のみ増やしても早すぎて測定できないため要素数を増やした)
var d=new Date();
for(var j=0;j<10;j++){
   arrayFill(10000,"12345678901234567890...");//実際には10000文字
}
(new Date())-d;
検証結果1
process1 test1 => 243ms
process1 test2 => 181ms
process1 test3 => 182ms

process2 test1 => 141ms
process2 test2 => 83ms
process2 test3 => 83ms

process3 test1 => 113ms
process3 test2 => 61ms
process3 test3 => 60ms
そして、次の2つの処理を検証する。
process4
//joinとsplitを使用し配列を作成
//(native codeで実行するので処理速度が速くなると期待)
function arrayFill(num,str){
    return (num = Number(num)) > 1
        ? Array(num + 1).join(str).split(RegExp('(?=(?:[\\s\\S]{'+str.length +'})+$)'))
        : [str];
}
process5
//再帰呼出し
function arrayFill(num,str){
    return num==0?[]:[str].concat(arguments.callee(num-1,str));
}
process5は再帰呼出しが多いと怒られた。process4にいたっては全てスクリプトタイムアウトしたので、計測可能になるまでそれぞれの値を減らして実施。
検証結果2
process4 test1'(1000回-10個-10) => 4639ms
process4 test2'(10回-500個-10)  => 7050ms
process4 test3'(10回-100個-100) => 1532ms

process5 test1 => 2455ms
process5 test2 => エラー(too much recursion)
process5 test3 => エラー(too much recursion)
遅過ぎる。話にならない。正規表現がまずかったのか。後で再度検討してみる。
(2007.12.02追記)
説明不足かもしれないから補足。正規表現の中身は悪いのではなくそもそも正規表現を使うのは処理コストが高いのではないかということ。

トラックバック

このエントリーのトラックバックURL:
http://www.kanasansoft.com/cgi/mt/mt-tb.cgi/67

この一覧は、次のエントリーを参照しています: 配列の初期値を指定する方法の処理速度検証:

» [JavaScript]JavaScriptでArray.fill 送信元 Thousand Years
Array.fill 配列の初期値を指定する方法の処理速度検証 (Kanasansoft Web Lab.)について。 Arrayをnullで初期化した... [詳しくはこちら]

» [.js] js.bench[1] = split || match 送信元 ’ellaneous
配列の初期値を指定する方法の処理速度検証 (Kanasansoft Web Lab.) ループに比べて遅いのは当然としても,そもそも split はこの... [詳しくはこちら]

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

Google