« クラス名のストリングからインスタンスを生成する | main | flashのeclipse開発環境ビデオチュートリアル »

2005年06月21日

超高速オブジェクト管理

000247.gif

昔Flashで、4~500個のMovieClipとオブジェクトを、如何に高速に管理するかという実験をしました。そんときのノウハウを公開。ちなみにサンプルはクリックして十字キーとスペースで動きます。

・はじめにオブジェクトを全て生成する
attachMovieとか、newとかやってると多分遅くなるので、全てオブジェクトを最初に生成しちゃいます。
 

・未使用インスタンス配列に登録
生成したインスタンスは、配列で管理します。
unused_ar.push(obj)みたいな感じで。
 

・使用する場合は、pop()で未使用インスタンスを配列から取り出す
obj = unused_ar.pop() みたいな感じで、インスタンスを配列から取り出します。このとき、obj.id=id++ といったように、インスタンスにIDを割り振ります
 

・使用中のインスタンスは、オブジェクト&連想配列で管理します
未使用インスタンスは配列に格納していましたが、使用中のインスタンスの管理には配列を使用しません。かわりにid名を用いて連想配列形式でオブジェクトに登録します
using_obj[ obj.id ] = obj
 

・使用中インスタンスをfor inで回して管理
for文よりも、for in文の方が処理速度が速いのでそちらを使います。ちなみにfor in文は再生順序が保障されてないのでご注意ください。しかしこの方法は、インスタンス破棄の速度でそれを上回るメリットをもたらします。

for(var id in using_obj){
using_obj[id].update()
}

 
・使用済みインスタンスの破棄
使用中のインスタンスはオブジェクトに格納して管理されています。
よって、使用後は delete using_obj[ obj.id ] で、for文走査なしで削除ができます。
一方、未使用のインスタンスは配列に格納して管理されています。よって unused_ar.push(obj) で即座に、使用済みになったインスタンスを返却できます。未使用インスタンスはすぐにpop(obj)で取得できるので、こちらでもループによる走査は必要ありません。
 

基本的にflashで重くなるのは、1に描画、2にfor文の走査、3にnewとdelete, attachMovieだと思うので、インスタンスの生成と削除管理から、for文を取り除くとムッチャ高速化できます。

投稿者 Taka : 2005年06月21日 13:05

book

dotfla.gif

bookmark

はてなブックマークに追加

del.icio.usに追加

trackbacks

this entry's trackback URL:
http://www.fladdict.net/cgi-bin/mt3/mt-tb.cgi/232

このリストは、次のエントリーを参照しています: 超高速オブジェクト管理:

» james blun from
james blunt high mp3 [read more]

トラックバック時刻: 2006年02月28日 21:22

» britney spears camel toe from
camel toe anna young camel toe [read more]

トラックバック時刻: 2006年02月28日 21:22

comment

ここで扱ってるのは連想配列なのでどのみちfor..in文しか使えないのですが

>for文よりも、for in文の方が処理速度が速いのでそちらを使います。
配列の場合はfor文の方が速いです。
もちろん、デクリメントの方がより速く。

by Munegon : 2005年06月22日 01:18

pushやpopだと可変長配列となって、それなりにオーバーヘッドがあるので
400個とかオブジェクト数を固定してしまうなら、固定長の配列を用意してしまって
要素番号をずらしながら随時入れ替え管理していく方がいいのではないでしょうか。

by Munegon : 2005年06月22日 03:20

>400個とかオブジェクト数を固定してしまうなら、固定長の配列を用意してしまって
要素番号をずらしながら随時入れ替え管理

すまんす。これ想像つかないっす。
固定長配列を用意すると、オブジェクトを休止させるときにまたfor文走査が必要になっちゃいませんでしょうか??

使用中のオブジェクトの数をカウントしておき、配列の前半を使用中、後半を待機として、仕様終了したオブジェクトは使用中オブジェクト末尾とスワップした上で、仕様終了フラグを立てる・・・という感じであってます?

swapDepthsみたいな感じ。

by Taka : 2005年06月28日 05:01

入れ替え管理と書きましたが、実際に要素同士をスワップする必要はないです。
使い終わったオブジェクトは、その都度使用中オブジェクトの末尾に格納するだけ。

使用中領域の格納オブジェクトは、ただ消さなかったために格納されているだけで
実際は可変長のオーバーヘッドを避けるためのゴミと考えてください。
タイミングによっては要素かぶってるぞ状態や、どこにも格納されてないぞ状態が出てきますが
使用するたびに要素番号をひとつ進める、終了するたびにひとつ戻すという
ルールを守る限りは問題ないと思います。

by Munegon : 2005年06月28日 21:43

なるほどー。時間あるときに挑戦してみますー。

by Taka : 2005年07月05日 13:00

コメントしてください




保存しますか?