Hatena::Groupactionscript

ConquestArrow.addEventListener();

2007-08-04

[][]Adobe - Developer Center : Tips for tuning ActionScript 3.0 performance for Flex and Flash developers 01:15 はてなブックマーク - Adobe - Developer Center : Tips for tuning ActionScript 3.0 performance for Flex and Flash developers - ConquestArrow.addEventListener();

ActionScript 3 Performance Tuning[PDF]というAdobe公式の資料が公開されていた。基本的にはいままでも言われてきたことだが、p.14のArray Member Accessは知らなかった。

  • Member access is as fast as C++ in dense portion
    • var a:Array = [1,2,3,4,5];
    • a[1000] = 2010;
    • a[1001] = 2011;
    • a[2]; //FAST PATH
    • a[1000]; //SLOW PATH

AS3の配列は可変長の配列だからどちらも遅いのかと思っていたが差があったらしい。

GulhermeGulherme2012/07/12 17:26To think, I was confused a mitnue ago.

tfhxwohbnotfhxwohbno2012/07/12 23:459vDFC2 <a href="http://wbebovcnygjo.com/">wbebovcnygjo</a>

scrdistkkrscrdistkkr2012/07/14 13:231v44Jo , [url=http://oxylniumlkpl.com/]oxylniumlkpl[/url], [link=http://zqlcxznpggxe.com/]zqlcxznpggxe[/link], http://jzipnqpdwrmd.com/

iqimaoqnrciqimaoqnrc2012/07/15 06:04KXfgSM <a href="http://obksmibnjgwn.com/">obksmibnjgwn</a>

yisgvswyisgvsw2012/07/15 11:06FqgI4A , [url=http://gpezoqyvwowu.com/]gpezoqyvwowu[/url], [link=http://bhyzgibgscwf.com/]bhyzgibgscwf[/link], http://pfjfdrusmsxe.com/

トラックバック - http://actionscript.g.hatena.ne.jp/ConquestArrow/20070804

2007-08-03

[][]いま使っているFD3用プラグイン 00:15 はてなブックマーク - いま使っているFD3用プラグイン - ConquestArrow.addEventListener();

FD3はdll形式のプラグインに対応している。デフォルトでも純正プラグインが複数入っているので、いじってみると面白い。

もちろん、サードパーティプラグインも数は多くはないが色々でている。以下に私が今使用しているプラグインを挙げてみる。

FlashDevelop Trace Plugin - — - Double-Quotes - —

trace出力を受け取る、のではなく、trace生成用プラグインfor in形式の出力にも対応している。デフォルトでは標準のtrace()が生成されるが、私の場合PluginのSettingsから設定可能なAlternate Functionに、FlashDevelop用のFlashConnect.atrace()関数*1を設定している。

//出力されるtrace文の例(Alternate FunctionはFlashConnect.atraceを設定)


private var hoge:Number;

//hogeを選択orキャレットを合わせてCtrl+0
trace( "hoge : " + hoge );
//hogeを選択orキャレットを合わせてCtrl+Shift+0
for( var i:String in hoge ) trace( "key : " + i + ", value : " + hoge[ i ] );
//hogeを選択orキャレットを合わせてCtrl+9
FlashConnect.atrace( "hoge : " + hoge );
//hogeを選択orキャレットを合わせてCtrl+Shift+9
for( var i:String in hoge ) FlashConnect.atrace( "key : " + i + ", value : " + hoge[ i ] );

SourceOptions

SE|PY開発者のAlessandro Crugnola氏によるFlashDevelop3用プラグイン

右クリックメニューに以下の機能を追加する。

  • import文の自動生成*2
  • getter/setterジェネレータ
  • アクセサメソッドジェネレータ
    • get_XXX()/set_XXX()というようなメソッドを自動生成

Bookmarks panel

SE|PY開発者のAlessandro Crugnola氏によるFlashDevelop3用プラグイン

FD3のBookmarkを一覧できるパネルを追加する。

ASClassWizard

SE|PY開発者のAlessandro Crugnola氏によるFlashDevelop3用プラグイン

AS2/3の新規クラス生成時にウィザード形式で生成できるようになる。使い方は、ProjectPanelから「右クリック > Add > New Class..」で。

*1:FlashDevelopのoutputパネルで所得できるようになる。

*2:手元ではうまく動かない??

JayJay2012/07/09 20:15Well put, sir, well put. I'll ceratnily make note of that.

mcmhqrnjamcmhqrnja2012/07/10 15:273GgpZY <a href="http://opzrujrhbaie.com/">opzrujrhbaie</a>

mbbjgfmbbjgf2012/07/12 11:44ZIOUYY <a href="http://xeausjlqdgjx.com/">xeausjlqdgjx</a>

frqyeycfrqyeyc2012/07/12 17:14luV5Bt , [url=http://gxubbjgollyl.com/]gxubbjgollyl[/url], [link=http://hhuoddcbttqo.com/]hhuoddcbttqo[/link], http://jjimbunsliil.com/

トラックバック - http://actionscript.g.hatena.ne.jp/ConquestArrow/20070803

2007-07-04

[][]いくつあるかわからない複数の数の最大値・最小値をMath.max()/Math.min()で求める方法 23:53 はてなブックマーク - いくつあるかわからない複数の数の最大値・最小値をMath.max()/Math.min()で求める方法 - ConquestArrow.addEventListener();

複数の数値の最大値・最小値を求めるには、Math.max()/Math.min()を使う。

var a:uint = 10;
var b:uint = 20;

trace("max",Math.max(a, b));	//max 20
trace("min",Math.min(a, b))l	//min 10

AS3では、Math.max()/Math.min()引数は可変長引数*1なので、2つ以上の数を比較することもできる。

trace("max",Math.max(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));	//max 10

3つ以上の数を比較できるのはなかなか便利なのだが、比較したい数の項目数がいくつあるかわからない時には使えない。

var a:Array = new Array();
for(var i:uint=0; i<someItemsLength; i++){
	a[i] = procItem(i);	//項目数が不定の配列
}

//配列aの項目の値の中で最大値を求めたい
Math.max(a[0], a[1], a[2], a[3], …);	//いくつあるか分からないので引数に渡せない

また、比較したい数の項目数が分かっていたとしても、項目数が多い場合にいちいち記述するのは面倒だ。

//100ある数のうち最大値を求めたい
Math.max(a, b, c, d, e, f, g, h, …	//全部書くの??

しょうがないので、配列を受け取って最大値・最小値を求める独自の関数を作ったりするのだが、やっぱりネイティブのAPIを使いたいもの。実は、次の方法で可能。

//任意の長さの配列
var a:Array = new Array();

Math.max.apply(null, a);	//配列aの項目の中での最大値が求められる

Function.apply()を使うのが肝。Function.apply()Function.call()とはことなり、第二引数は配列である。なので、Math.max()/Math.min()のように可変長引数の関数に、配列の中身を引数として渡すことが可能になる。

基本といえば基本なのだが、うっかり忘れがちなのでメモ。

*1:いわゆる、「...rest」

FarazFaraz2015/09/30 16:42So much info in so few words. Tolosty could learn a lot.

NaTaliaNaTalia2015/10/09 07:36You get a lot of respect from me for writing these helpful <a href="http://ugheifvi.com">arcleits.</a>

HeldaHelda2015/10/09 11:59What a plauesre to find someone who thinks through the issues http://grxrdvb.com [url=http://virdwla.com]virdwla[/url] [link=http://gtdprbx.com]gtdprbx[/link]

StarlyStarly2015/10/10 06:42It was dark when I woke. This is a ray of <a href="http://uuozdfvm.com">sunishne.</a>

YoshieYoshie2015/10/12 07:12I could watch Scniedlhr's List and still be happy after reading this. http://ewlkhoqb.com [url=http://zzopexb.com]zzopexb[/url] [link=http://gtcsgj.com]gtcsgj[/link]

2007-06-21

[]ActionScript3 最適化・高速化Tips 簡易まとめ 02:16 はてなブックマーク - ActionScript3 最適化・高速化Tips 簡易まとめ - ConquestArrow.addEventListener();

優れたインタラクションを支えるのは優れた実行時パフォーマンスであり、快適な操作を支えるのは1msecでも処理時間を減らす努力である。

そんなわけでAS3の最適化に関するTipsを英語圏の記事からまとめてみた。


Daniel Hai ≫ Re-use your BitmapData objects, speed up your apps

フレーム毎にビットマップ処理が必要な場合、前もってビットマップデータを作成しておき、fillRect()/copyPixels()を使う

1) When doing per-frame bitmap operations, create and store a bitmap outside of the per-frame operation, and do a fillrect per-frame.

10000 operations of “BitmapData.draw()” 4068 ms
10000 operations of “new BitmapData()” : 2324 ms
10000 operations of “BitmapData.clone()” 1012 ms
10000 operations of “BitmapData.copyPixels()” 962 ms
10000 operations of “BitmapData.fillRect()” : 515 ms

BitmapData.draw()BitmapData.fillRect()に変えると約790%の高速化になる。実際にはfillRect()だけでは十分でないのでcopyPixels()をメインに使うことになるだろう。それだけでも約420%の高速化だ。

Some ActionScript 3.0 Optimizations - Web Development Blog

forループで配列内走査をする場合は前もって配列の長さを所得しておき、イテレータ変数をint/uint型にする

Array indexing

AS3に限った話ではないが、ごくごく基本的な高速化処理。特に必要がない限り、この書き方にすべき。これだけで約147%の高速化。

余談だが、以前LightboxJSのソースを読んだときに、この処理をしていなくて驚いた。世界中で使われることを考えると、全体ではとんでもないムダをしていることになる。個人的にAjaxを信用していない理由のひとつだ。JavaScript開発者の実行時パフォーマンスに対する意識は正直もっと高くてよい。

他のクラスの定数は一旦ローカルの変数に値を代入してからループでつかう

Constants from other classes

約115%の高速化。

ローカル変数宣言は1行にまとめる

This can be speeded up if you use the "var" keyword one time and then declare the variables on a single line

Some ActionScript 3.0 Optimizations - Web Development Blog

Cなどでよく見かける書き方ではあるが、同時に注意が必要な書き方でもある。約135%の高速化が実現。

ビット演算を用いる

AS1/2では効果がなかったが、AS3では多くのプログラミング言語と同じく、ビット演算は高速である。

どれぐらい速いかは、後述。

andre michelle - gamedev | musicware - berlin is in germany ≫ Blog Archive ≫ AS3 optimations & suggestions


(AS2のように)条件文や命令文を書き換えない

Do not overload condition and statements as in AS2

andre michelle - gamedev | musicware - berlin is in germany ≫ Blog Archive ≫ AS3 optimations & suggestions

どうやらAS2では高速化されたようだが、AS3では素直に書いた方が速いらしい。

Object型は使わない

Do not use Objects, if you know, which properties will be finally involved.

andre michelle - gamedev | musicware - berlin is in germany ≫ Blog Archive ≫ AS3 optimations & suggestions

できる限りクラスを定義する。同じ意味で*型もできるだけ避けるべき。

配列の要素を読むときは型のキャストをする

Cast instances, while reading from an Array

andre michelle - gamedev | musicware - berlin is in germany ≫ Blog Archive ≫ AS3 optimations & suggestions

たしかそのままだと*型と同じように処理されるはずなので、できるかぎりキャスト。

mxmlcで有効なメタデータタグ、[ArrayElementType("hogehoge")]が効果があるかどうかは不明。

できる限り、int型を使う

Try to use Integers (int) for all possible cases

andre michelle - gamedev | musicware - berlin is in germany ≫ Blog Archive ≫ AS3 optimations & suggestions

Number型よりもint/uint型の方がサイズが小さいので速くなる。

とはいえ、AS3は内部的にはNumber型で扱われるので、かならずしも速くなるわけではないことに注意。

ビット演算はとても早い

Bitoperators are lightning fast

andre michelle - gamedev | musicware - berlin is in germany ≫ Blog Archive ≫ AS3 optimations & suggestions

さらに後述。

Daniel Hai ≫ More performance tuning in Actionscript 3

Point型やRectangle型などよく使うオブジェクトの定数をつくって使いまわす

Create constants for commonly used objects, such as new Point(0,0), new Rectangle(0,0,320,240), etc. This reduces overhead of creating new objects.

Daniel Hai ≫ More performance tuning in Actionscript 3

AS3になって使う機会の増えたPoint型/Rectangle型を使いまわす。これで838%の高速化。

パッケージ変数・定数やパッケージ関数をつかってできる限りクラス名参照を減らす

Reduce pointers to static class names as much as possible, use package variables and functions instead.

Daniel Hai ≫ More performance tuning in Actionscript 3

ネイティブのMathクラスの関数などにも有効などの複雑な数学演算は大分効果が期待できる。

ファイルサイズ削減にも有効な場合が。

(.graphics.transformなどの)グローバルgetterプロパティを2回以上呼ぶ場合は、ローカル変数に代入して使う

Store getter properties as local variables when using them more than once in a method (such as .graphics, .transform)

Daniel Hai ≫ More performance tuning in Actionscript 3

これは書きやすさ、という意味でも効果的。一般的に実行時パフォーマンス最適化のTipsは開発パフォーマンスを下げるもの*1だが、これは珍しくどちらにも効果アリ。…というかAS3の設計ミスじゃないかと思ったり思わなかったり。必ず使うようにしたい。18%の高速化。

なお、.stageプロパティはパッケージ変数に入れておくと118%の高速化になるらしい。ひとつまえとの組み合わせ技。

getDefinitionByName(getQualifiedClassName(object))を使う代わりにカスタムリフレクションメソッドを作る

Create custom reflection methods instead of using: getDefinitionByName(getQualifiedClassName(object))

Daniel Hai ≫ More performance tuning in Actionscript 3

なんと、5,489%の高速化。あまりつかいそうではないとはいえ、無視できない数字。

polygonal labs ≫ Bitwise gems - fast integer math

2の累乗を掛ける場合は左シフトを使う

Left bit shifting to multiply by any power of two

300%の高速化。

2の累乗を割る場合は右シフトを使う

Right bit shifting to divide by any power of two

350%の高速化。

int整数変換は「>> 0

Number to integer conversion

10%高速化。

int型の変数の入れ替えにはXOR演算

Swap integers without a temporary variable using XOR

こういう処理をするかどうかはともかく。20%高速化。

var t:int = a;
a = b;
b = t;

//equals:
a ^= b;
b ^= a;
a ^= b;

追記:abが同じ変数だった場合は必ず0になるので注意。同じ値の別の変数の場合は問題ない。詳細はコメント参照。

符号の変換にはNOT演算やXOR演算を使う

Sign flipping using NOT or XOR

300%高速化。

2の累乗で剰余を取る時は、AND演算をつかう

Fast modulo operation using bitwise AND

modulus = numerator & (divisor - 1);

600%高速化。

AND演算で偶数判断する

Check if an integer is even/uneven using bitwise AND

600%高速化。

Math.abs()を使わず絶対値を求める

Absolute value

//version 1
i = x < 0 ? -x : x;

//version 2
i = (x ^ (x >> 31)) - (x >> 31);

この単純なコードでなんと2,500%高速化。さらにビット演算を組み合わせるとさらに加えて20%高速化。

2つのint型変数の符号が一致するかどうかを調べるときは、「eqSign = a ^ b >= 0;

Comparing two integers for equal sign

35%高速化。

R5G5B5からR8G8B8へのピクセルフォーマット変換にはビットシフトをつかう

Fast color conversion from R5G5B5 to R8G8B8 pixel format using shifts

まとめ

  • 基本
    • forループで配列内走査をする場合は前もって配列の長さを所得しておき、イテレータ変数をint/uint型にする
    • 他のクラスの定数は一旦ローカルの変数に値を代入してからループでつかう
    • ローカル変数宣言は1行にまとめる
    • (AS2のように)条件文や命令文を書き換えない
    • Object型は使わない
    • 配列の要素を読むときは型のキャストをする
    • できる限り、int型を使う
    • Point型やRectangle型などよく使うオブジェクトの定数をつくって使いまわす
    • パッケージ変数・定数やパッケージ関数をつかってできる限りクラス名参照を減らす
    • (.graphics.transformなどの)グローバルgetterプロパティを2回以上呼ぶ場合は、ローカル変数に代入して使う
    • getDefinitionByName(getQualifiedClassName(object))を使う代わりにカスタムリフレクションメソッドを作る
  • 描画
  • ビット演算化
    • 2の累乗を掛ける場合は左シフトを使う
    • 2の累乗を割る場合は右シフトを使う
    • int整数変換は「>> 0
    • int型の変数の入れ替えにはXOR演算
    • 符号の変換にはNOT演算やXOR演算を使う
    • 2の累乗で剰余を取る時は、AND演算をつかう
    • AND演算で偶数判断する
    • Math.abs()を使わず絶対値を求める
    • 2つのint型変数の符号が一致するかどうかを調べるときは、「eqSign = a ^ b >= 0;
    • R5G5B5からR8G8B8へのピクセルフォーマット変換にはビットシフトをつかう

なお、数値は実際に私が測定したわけではないので、実際は変わる可能性が高い。


おまけ:経験則での最適化Tips

未確認多数につき、要確認。

  • TextField.textに文字列を追加するときは「+=」でつなげるのではなくappendText()をつかう*2
  • フィルタのblurX,blurYプロパティの値は2の累乗にする*3
  • 変数のうち、可能なものはできるかぎり定数化
  • ループの内部からできる限り処理を追い出す
  • 参照はできるかぎり短く

追記:注意点

多くの人に注目されたようなので注意点。基本的にこういう最適化は「わかっている人」向けなので、よく吟味してから使用されたし。特にビット演算を使った最適化は直感的でないので、仕組みをよく理解していないと思わぬバグの原因になりかねない。

ちなみに、ビット演算系の最適化は他の堅めの言語だとポピュラーな手法で、そのあたりのノウハウはマダマダAS3でも使えそうな感じ。AS3のいいところは、基本は超高級言語ながら、やろうと思えばこういうある意味古典的なこともできるところだと思う。

さらにおまけ

*1:なので、最適化は開発の最後の方に行うのが定石

*2mxmlcの警告より

*3リファレンスより

38382007/06/21 14:58> int型の変数の入れ替えにはXOR演算
a == b の時は使えないですね。

svasva2007/06/22 09:41え、使えないの?

a=0; b=0;
a ^= b; //→(1,0)
b ^= a; //→(1,1)
a ^= b; //→(0,0)

a=1; b=1;
a ^= b; //→(0,1)
b ^= a; //→(1,0)
a ^= b; //→(1,1)

だから使える気がする

38382007/06/22 13:16つかえました。すいません。。。

ConquestArrowConquestArrow2007/06/22 23:31>a == b の時は使えないですね。

ちょっと調べてみましたが、svaさんのコメントの通り、「a == b」つまりaとbが同じ値でも別の変数である時は使えます。

問題は、【aとbが同じ変数】の時ですね。

つまり、
a ^= a;
a ^= a;
a ^= a;
の時は必ずaは0になってしまいます。

これを変数の入れ替えと呼ぶかはともかく、関数化していた場合などには注意が必要そうです。

TeinaTeina2012/07/09 20:06I want to send you an award for most helpful itnerent writer.

nponqknponqk2012/07/10 15:25jnXoHz <a href="http://ofnldtfjybgr.com/">ofnldtfjybgr</a>

czkamdgiczkamdgi2012/07/12 11:41RTRWQ9 <a href="http://xbybdmhzekvf.com/">xbybdmhzekvf</a>

pfavxktypfavxkty2012/07/12 17:12e9dBr0 , [url=http://hmjvkfoxwsiw.com/]hmjvkfoxwsiw[/url], [link=http://ycnauvqlyioy.com/]ycnauvqlyioy[/link], http://tfqthbxjiyit.com/