一時変数の効率化
以前のお仕事でパーティクル演算を使うことがあって海外のサンプルコードなど眺めていて気づいたことです。
一時変数の扱いについて知らなかったことだったのでメモっておきます。
var x:Number = 100;
変数をブロック内( {と} の中)で宣言すると、一時変数として宣言されます。
一時変数はブロック内でつかい終わると破棄される上に、参照経路が少ないため、グローバル変数やインスタンスメンバ(タイムライン変数含む)と比較してメモリ効率がよいです。
そこでforなどのブロックでも多用するのですが、実は一時変数のスコープ(参照可能な範囲)は関数単位となるため、forなどのブロックないの変数は結局何回宣言しても同じスコープの中で再定義しているに過ぎず、宣言のオーバーヘッドの分よぶんなことをしていることになります。
ですので、ループのブロック内でしかつかわない変数も、 衝突判定やパーティクル演算などかなり多くのオブジェクトを処理するときには、 (見づらいですが) forブロックの外で宣言したほうが負荷が低いようです。
// forの中で宣言 for( var i:Number=0,num:Number=particles.length; i<num; ++i ) { var p:Object = particles[i]; var nextX:Number = p.x +p.vx; var nextY:Number = p.y +p.vy; //何か処理 }
// forの外で宣言 var p:Object; var nextX:Number; var nextY:Number; for( var i:Number=0,num:Number=particles.length; i<num; ++i ) { p = particles[i]; nextX = p.x +p.vx; nextY = p.y +p.vy; //何か処理 }
これで宣言自体の負荷がlength 回数分減ります。
ただしちょっと見づらいのと、同じスコープ内にいくつかループがあるときに初期化わすれなどリスクなど注意です。
また1回ごとのコストはものすごく微小なものなので、あまりこだわってもかけた時間に対してたいして最適化できないことがあります。
それ以前に最適化の方法は小数点を使った処理をなるべくしないとか、描画に関わるところをみなおすとかもっと効果的なものがたくさんありますので、これさえやればというわけじゃないですが、大量の処理をする場合はとても効果が大きいので重いときはチェックしてみましょうー。