サイトトップ

Director Flash 書籍 業務内容 プロフィール

Adobe Flash非公式テクニカルノート

オブジェクトを使い回す

ID: FN1111002 Product: Flash CS4 and above Platform: All Version: 10 and above/ActionScript 3.0

[ヘルプ]の[Flash Platformのパフォーマンスの最適化]/[メモリの節約]/[オブジェクトの再利用]には「可能な場合は、同じオブジェクトを繰り返し作成する代わりに再利用」することが勧められています。本ノートではこのお題について考えてみます。


01 なぜオブジェクトを使い回すとよいのか
オブジェクトを使い回すと何がよいのかというと、理由は大きくふたつ挙げられます。

  1. オブジェクトは新たにつくるより設定し直す方が速い
  2. 古いオブジェクトを片づけるガベージコレクションの手が煩わされない

第1に、新たにインスタンスをつくるより、すでにあるオブジェクトを初期化したり、設定し直す方が基本的には速いです。第2に、前のオブジェクトを捨てて(たとえば変数を上書きして)新たなインスタンスをつくると、要らなくなったオブジェクトは「ガベージコレクション」により片づけられます[*1]。ところが、ガベージコレクションは重い処理なので、すぐには働きません。すると、繰返し処理が多ければ、大量の不要なオブジェクトがガベージコレクションを待つ間メモリに残ることになります。オブジェクトを使い回せば、このガベージコレクションの手を煩わせずに済みます。

つまり、オブジェクトを使い回すと処理が速くなり、CPUやメモリを無駄に費やすことがなくなるのです。そこで、いくつかのクラスのオブジェクトを例にして、使い回し方をご紹介します。

[*1]「ガーベジコレクション」(garbage collection)とは、オブジェクトへの参照を確かめ、すべての参照がなくなるとメモリを自動的に解放する仕組みです。なお、拙著『ActionScript 3.0による三次元表現ガイドブック』Column 01「ガベージコレクションと弱い参照」(PDFプレビュー公開)p.024-025およびF-site「DisplayObjectインスタンスの削除とガベージコレクション」をご参照ください。


02 オブジェクトのプロパティを設定し直す
多くのクラスでは、コンストラクタメソッドに引数を与えて、新たなインスタンスに初期設定が加えられます。それらの設定は通常プロパティとして備わっているので、後から変えることができます。したがって、そうしたプロパティを設定し直せば、オブジェクトが使い回せます。

たとえば、矩形領域を定めるRectangleクラスのコンストラクタメソッドには、4つの引数が渡せます。Rectangleインスタンスを新たにつくるときと、オブジェクトを使い回す場合はつぎのようになります。

【新たなインスタンスをつくる】
var myRectangle:Rectangle = new Rectangle(x座標, y座標, 幅, 高さ);

【オブジェクトを使い回す】
myRectangle.x = x座標;
myRectangle.y = y座標;
myRectangle.width = 幅;
myRectangle.height = 高さ;

ふたつの処理の速さを比べるために、wonderflにテスト用のコードを上げました(wonderfl 001)。

wonderfl 001■Rectangleオブジェクトの新規作成と再利用の比較

Recycling vs Creating objects - wonderfl build flash online


03 オブジェクトをメソッドで初期化して使い回す
クラスによっては、オブジェクトを初期状態に戻すメソッドが備わっています。そうしたメソッドがあれば、プロパティをひとつひとつ設定する手間が省けます。

たとえば、MatrixクラスにはMatrix.identity()メソッドがあります[*2]。Matrixオブジェクトに対してこのメソッドを呼出せば、引数なしのコンストラクタメソッドでつくるのと同じデフォルト(単位行列)のインスタンスになります。Matrixオブジェクトを初期化して使い回すのはとても簡単です。

【新たなインスタンスをつくる】
var myMatrix:Matrix = new Matrix();

【オブジェクトを使い回す】
myMatrix.identity();

もちろん、Matrix.identity()メソッドの方が、コンストラクタメソッドを呼出すより速いです。ふたつの処理の速さを、wonderflのテスト用のコードで比べてみました(wonderfl 002)。

wonderfl 002■Matrixオブジェクトの新規作成とメソッドによる初期化の比較

Recycling vs Creating objects 2 - wonderfl build flash online


[*2] Matrixクラスの扱いと数学的な捉え方について詳しくは、それぞれAdobeデベロッパーセンター「Matrixクラス − 変換行列1」と「変換行列を数学的に捉える」をお読みください。


04 配列やVectorオブジェクトを空にして使い回す
配列やVectorオブジェクトも、新たにインスタンスをつくるより、使い回した方がお得です。けれど、これらのクラスに初期化のメソッドは備わっていません。だからといって、forループでエレメントをすべて削除する必要はありません。長さのプロパティArray.lengthまたはVector.lengthプロパティに0を設定すればよいのです。

【新たなインスタンスをつくる】
var my_array:Array = [];

【オブジェクトを使い回す】
my_array.length = 0;

なお、「配列を初期化するには」Arrayクラスのコンストラクタメソッドを呼出すより、配列アクセス演算子[]を使った方が速いです。コンストラクタメソッドを使う場合も含めて、新たな配列の作成と使い回しの速さをwonderflのテスト用コードで比べました(wonderfl 003)。念のため、Vectorクラスもforkしてテストしました。

wonderfl 003■配列の新規作成とArray.lengthプロパティによる初期化の比較

Initializing Arrays - wonderfl build flash online



作成者: 野中文雄
作成日: 2011年11月10日


Copyright © 2001-2011 Fumio Nonaka.  All rights reserved.