for ループでの配列長の括り出しは JavaScript でも有効か
「今週の話題」でもご紹介しましたが、先週、以下の記事が話題になっていました。
ActionScript3 最適化・高速化Tips 簡易まとめ
ActionScript3 で効率の良いコードを書くための Tips がまとめられていて、私も興味深く読ませていただきました。その中に for ループで配列を操作する場合には配列長をあらかじめローカル変数に代入しておくと 147% 高速化されるという項目があり、このテクニックは JavaScript でも適用すべきである、となっていました。
実は私もけっこう平気で Array.length を書いてしまうほうなので(C/C++ あがりの風上にも置けませんね ^^;)、もし事実であれば今後は注意しなくてはいけません。しかし、実際のところ ActionScript と JavaScript では実行時の仕組みがだいぶ異なるはずで、 ActionScript の最適化テクニックがそのまま通用するとは限りません。そんなわけで、効果を確かめるべく実験してみることにしました。
実験に使ったのは以下のコードです。
配列長を直参照
var array = new Array(1000000); var begin = new Date(); for(var i = 0 ; i < array.length ; ++i) { array[i] = i; } alert(new Date() - begin);
配列長を括り出し
var array = new Array(1000000); var begin = new Date(); var len = array.length; for(var i = 0 ; i < len ; ++i) { array[i] = i; } alert(new Date() - begin);
これらのコードを Opera 9.21, Firefox 2.0.0.4, IE6 (SP2) でそれぞれ 5 回ずつ実行し、平均を取ってみました。マシンは Libretto U100, Windows XP Professional SP2 です。
う〜ん、確かに速くはなるのですが、その差は僅か 2 〜 4% です。しかも単純ループでこの数字なので、ループ内の処理が複雑になれば、ほぼ誤差範囲に収まってしまうように思います。正直、ここまで差が出ないとは私にとっても意外でした。 1 割くらいは速くなると予想していたのですが・・・。
というわけで、どうやらこの件に関しては、あまり几帳面になる必要もないようです。私の浅い経験上ですが、 JavaScript ではコーディング面での最適化はあまり効果を発揮しない傾向があります。おそらく個々の演算がもともと重いので、ネイティブコードの呼び出しや数回のハッシュ・ルックアップくらいはオーバーヘッドにならないのでしょう。それよりも、実際の処理量自体を削減するアルゴリズム的な最適化を念頭に置くほうが効果的かと思われます。
ただし、あくまで for の条件部分のみに Array.length が出てくる場合の話なので、あまり鵜呑みにしないでください。ループ内で何回も参照するなら、その分だけ括り出す意味が出てくるでしょう。このあたりはケースバイケースで考えるしかなく、感の見せどころともいえますね。できるだけメンテナンス性を落とすことなく、効率よく最適化を行いたいものです。
詳しくはこちらの記事をどうぞ!
この記事にコメントする