先週はGoogle Developer Day 2009に行ってきまして、非常に有意義なセッションもあれば、それなりのものもありましたが。
今回は個人的に最も良かったパメラさんのGoogle Maps高速化セッションから、大量マーカーの効果的なプロット方法…は、また今度時間がある時にして、その際に彼女がポロっと漏らした「+=は-=に比べて遅いし」を軽く検証してみました。(FOXでアメリカン・アイドルを観ながら)
検証は、ループカウンタをアップしていく/ダウンしていく方法で比較しています。
※2009.09.27
検証プログラムの問題を指摘いただき、末尾に追加してあります。
検証プログラム
/* (1) sum */ var s = get_ms(); for(var i=0; i0; --i){ arr[i] = i; } var e = get_ms(); dump(e-s);
get_msはミリ秒を取得する関数、dumpは結果を出力する関数として用意しました。arrは、500,000個の添え字を持つ単純な配列です。
これを、公平を期すために同一プロセス内で交互に実行します。結果の単位はミリ秒となります。
結果
[Firefox3.0.1]
(1) 107 (2) 92 (1) 106 (2) 92 (1) 107 (2) 90 (1) 107 (2) 92
足し算、引き算の順です。
[Internet Explorer 7]
IEはFFに比べてこの実験では遅く、しかも「スクリプトの実行に時間が…」というエラーが出てしまいます。止める方法はあるのでしょうが、調べるのも面倒なので、配列のサイズを200,000に減らし、繰り返し回数も減らしてあります。
(1) 110 (2) 94 (1) 125 (2) 93 (1) 110 (2) 93
まとめ
疑う余地はなく、減算の方が高速という結果が出ました。FF2やIE8などはTV前のここの環境には無いので試していませんが、傾向としては充分だと思います。
特に大きなループでは可能ならば和算よりも減算を使うようにするのが良さそうです。
なお、カウントダウンでのループが可能なアルゴリズムであれば、比較演算も省略できる次の形の方が、より高速でした。
/* (3) while-subtract */ var s = get_ms(); var i=arr.length; while(--i){ arr[i] = i; } var e = get_ms(); dump(e-s);
[Firefox3.0.1]
(1) 110 (2) 91 (3) 77 (1) 106 (2) 92 (3) 77
コード量も少なく、お勧めの記述です。
2009.09.27追記
コメント欄で指摘をいただきました。
初歩的なミスで、lengthの評価回数が釣り合っておりませんでしたので、改めてやってみます。
var len = arr.length; /* (1) sum */ var s = get_ms(); for(var i=0; i0; --i){ arr[i] = i; } var e = get_ms(); dump(e-s);
結果
[Firefox3.5.3] (500,000ループ)
(1)100 (2)97 (2)100 (1)95 (2)100 (1)97
[Internet Explorer 8] (200,000ループ)
(1)47 (2)62 (1)47 (2)62 (1)47 (2)63
[Chrome 2] (5,000,000ループ)
(1)29 (2)26 (1)29 (2)26 (1)28 (2)25
再まとめ
結果、FF3.5やChrome2では傾向は変わらないものの、その差は縮まりました。
また、IE8では寧ろ加算の方が速くなっています。
前回テストした際のバージョンに該当するブラウザが手元に無いので比較実験になっていませんが、加減算の速度差は気にするほどではないと言えるかもしれません。
No related posts.
(メールアドレスはダミーです)
この検証プログラムには問題があると思います
とするのが適切であると思います
というのも加算側のコードは1ループごとにarr.lengthが評価されるので
減算側のコードに比べて遅くなるのは当然です
純粋に加算と減算を比較するのであれば加算側のループは
for(var i=0,imax=arr.length; i
ご指摘いただいた通りです。
差し当たり、lengthの評価を行わない形に変えて再検証してみました。
ありがとうございました。