前回に引き続き変数宣言の有無による違いを少し追求してみたいと思います。今回はパフォーマンスの違いについてです。よく知られている話だとは思いますがいちおう。
変数宣言の有無とパフォーマンス
まずは、以下のコードを考えます。Date のオブジェクトを生成して getTime() メソッドを 10 万回呼び出しています。変数宣言は行われていません。
date = new Date() for (i=0; i<100000; i++) date.getTime()
手持ちの環境で上のコードを実行してみます。すると、for ループの箇所の実行に約 470ms かかりました。
これを下のように変えてみます。2 行目で var を使った変数宣言を追加しています。それから for ループ内では、2 行目で新しく追加した変数経由でメソッドを呼び出しています。
date = new Date() var dateVar = date // 追加 for (i=0; i<100000; i++) dateVar.getTime()
こちらはループの実行に約 340ms かかりました。処理時間が 130ms 程短縮されています。
for ループ内で参照しているオブジェクトは、どちらのケースも同じく Date のインスタンスです。両者の違いは、参照に使用している変数の宣言に var が付いているかどうかだけです。このことから var 無しの変数からオブジェクトを参照する行為には、ずいぶん余計な時間がかかっていることが分かります。
関数内で var を付けて宣言した変数をローカル変数といいます。上の結果が示すようにこローカル変数へのアクセスは高速です。また、ローカル変数の有効範囲は宣言された関数内のみですので、参照の消し忘れによるメモリリークの心配もありません。
一方、var 無しで変数を使用した場合は、前回見たように、クラス内で有効な一種のグローバル変数になります。上の結果のとおり、グローバル変数へのアクセスはローカル変数より時間がかかります。
型注釈の有無とパフォーマンス
次は、変数宣言に型注釈をつけてみます。2 行目の宣言で明示的に Date 型を指定しています。
date = new Date() var dateTyped:Date = date // 型を指定 for (i=0; i<100000; i++) dateTyped.getTime()
実行してみるとループの箇所に約 300ms かかりました。先程の 340ms と比べ更に一割ほど短縮されています。
これは、AS3 の実行環境が型情報をパフォーマンス向上に役立てる機能を持っているからです。また、型注釈をつけるとメモリの使用量を減らす効果もあります。このような実行環境による型情報のサポートは AS3 の大きな特徴です。(注:この箇所は dynamic なクラスのオブジェクトに動的に追加されたメソッドやプロパティには当てはまりません)
変数宣言の追加とここまでのまとめ
さて、よく見ると、ループ内には i という変数も使われています。これもローカル変数として宣言してみます。
date = new Date() var dateTyped:Date = date for (var i=0; i<100000; i++) // i をローカル変数に dateTyped.getTime()
この結果、約 20ms になりました。i は 2 回使われている分効果が大きいようです。
さらに i に型をつけてみます。
date = new Date() var dateTyped:Date = date for (var i:int=0; i<100000; i++) // i を int 型に dateTyped.getTime()
これで約 13ms になりました。最初の数値である 470ms と比べて 3% 以下になっています。
var とか型とか書くのを習慣にしたほうがよさそう、という結論になりそうですが、10 万回繰り返してやっとこの程度の差という見方もできます。ここでの例のように後から変数宣言を追加すればよい話ですし、パフォーマンスの観点からだけなら、あまり神経質にならなくてもよいかもしれません。特に、型注釈の有り無しによる差はほとんど無いケースも多かったりします。
ただ、前回説明したように、グローバル変数 (var を使った宣言無しの変数) の使用はプログラムの構造を分かりにくくする可能性があります。パフォーマンスの件と併せると、特に理由の無い限り避けた方が賢明そうですね。
そうすると、ここまでのまとめとしては、
- var は基本的に付ける
- 型注釈はあったほうがまし
ということになります。
が、型注釈が無いことでプログラムの実行結果が非常に分かりにくくなる場合があったりします。次はこの点について掘り下げてみようと思います。
コメントする