無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

配列を列挙するとき、逆に回すと早い

JavaScriptで配列を列挙するとき、

for ( var i = 0; i < array.length; i++ ) {}

と書くより、

var length = array.length;
for ( var i = 0; i < length; i++ ) {}

とした方が早いらしい。理由は「配列の長さを参照するのが遅い」からで、上の方だとループ回数分長さの参照が行なわれるので低速になるとのこと。で、下のコードみたいに配列の長さを一旦変数で受けておくと参照回数が減るので早くなるんだけど、一行増えるのが嫌だ。というか、この理由なら配列を逆に回せば早いんじゃね?と思って試してみた。

/**
 * メソッドの実行時間を計る
 */
function perf( f ) {
   var count = 1; // 試行回数
   var total = 0;
   var max = null;
   var min = null;
   for ( var i = 0; i < count; i++ ) {
       var start = new Date();
       try {
           f();
       } finally {
           var time = new Date().getTime() - start.getTime();
           total += time;
           if ( max === null || max < time ) { max = time; }
           if ( min === null || min > time ) { min = time; }
       }
   }
   return { avg: Math.floor((total / count)), max: max, min: min } ;
}

// メイン関数
function main() {
   var array = new Array(1000000);
   var fs = {
     "普通にループ" : function() {
       for ( var i = 0; i < array.length; i++ ) {}
     },
     "サイズを一旦変数で受ける" : function() {
       var length = array.length;
       for ( var i = 0; i < length; i++ ) {}
     },
     "逆にループ" : function() {
       for ( var i = array.length-1; i >= 0; i-- ) {}
     }
   }
   var stdout = document.getElementById( "out" );
   for ( var key in fs ) {
     stdout.innerHTML += key + " : " + perf(fs[key]).avg + "<br/>";
   }
}

実行はこちらから。

手近にあったブラウザでの計測結果は以下の通り。

FireFox3 IE6 Safari3(Windows版) Opera 9 Google Chrome 0.3
普通にループ 124ms 500ms 203ms 312ms 8ms
サイズを一旦変数で受ける 81ms 109ms 94ms 219ms 6ms
逆にループ 62ms 109ms 93ms 187ms 3ms

うむ、確かに多少は早い。なお、使えるのは逆に回しても問題ない場合だけなので注意な!(←当たり前)


ところで、こういう話、昔のJavaにもあったなー。for文を回すときにiをインクリメントするよりもデクリメントする方が早いとかなんとか。(確か数値の比較が、0を比較する場合とそれ以外で違う、とかだったような気がする)で、

for ( int i = array.length-1; i >= 0; i-- ) { ... }

↑みたいなforループがたくさん書かれていたのだけど、JavaVMのバージョンアップで差がなくなって、後には謎のfor文だけが残ったとか。いや、それほど謎ではないけどさ。


まぁ、こんな話もあり、個人的にはボトルネックでもない限り、シンプルな書き方を選択した方がいいんじゃないかと思うわけです。よほど巨大な配列を扱う場合でなければ、性能もそんなに変わらないし変にこだわる必要はないかと思います。