コレクション速度比較
2008/08/25 21:26 - AS3.0
Array、ByteArray、そして FlashPlayer10 から新たに加わった Vector。
ActionScript 3.0 には上記三つのコレクション型データ構造がありますが(Dictionary は若干性質が違うので、今回は除外しています)、実際んとこ、これら三つは速度的にどんだけ違うのか、必要があったんで調べてみました。
型については以下の5種類を対象としました。
- ブール値
- 数値( uint と Number )
- 文字列
- Shape
- TypoLetter
最後の TypoLetter というのは私のカスタムクラスです。
これら5つの型を FREQUENCY_OF_TRIAL 個扱ったときどれくらいの時間を要するのかを、以下の7タイプのコレクションで調べてみました。 プリミティブ型については、5万個と500万個の2種類を試します。
また、プリミティブ型のデータでは各コレクションごとにデータを生成していますが、非プリミティブ型のデータでは、最初に FREQUENCY_OF_TRIAL 個の当該型データインスタンスを生成し Array に格納、各コレクション生成時はその Array からデータを取り込むということをしています。
- Array(FREQUENCY_OF_TRIAL)
- Vector.<type>(FREQUENCY_OF_TRIAL, true)
- Vector.<type>()
- Vector.<Object>(FREQUENCY_OF_TRIAL, true)
- Vector.<Object>()
- ByteArray.writeXXXX()
- ByteArray.readXXXX()
蛇足ながら、コレクションのタイプはそれぞれどんな状態かというと以下のとおり。
- Array 生成時に個数を指定
- Vector の type を格納対象型にして、長さを固定する
- Vector の type を格納対象型にして、長さを固定しない
- Vector の type を格納対象型ではなく Object にして、長さを固定する
- Vector の type を格納対象型ではなく Object にして、長さを固定しない
- ByteArray に書き込み
- ByteArray から読み込み
以下結果。 なお、環境は以下のとおり。
- FlashDevelop 3.0.0.31783
- flex_sdk_3.0.3.2490
- Adobe Flash Player ver 10.0 b218
- Windows XP SP3
- AMD Athlon(tm)XP-M 2400+ 1.80GHz
- 736 MB RAM
プリミティブ型
ブール値
type Boolean FREQUENCY_OF_TRIAL : 50,000 22 ms : Array 0 ms : Vector Boolean fixed=true 21 ms : Vector Boolean fixed=false 4 ms : Vector Object fixed=true 23 ms : Vector Object fixed=false 22 ms : ByteArray writeBoolean 15 ms : ByteArray readBoolean
type Boolean FREQUENCY_OF_TRIAL : 5,000,000 1467 ms : Array 420 ms : Vector Boolean fixed=true 1384 ms : Vector Boolean fixed=false 471 ms : Vector Object fixed=true 1361 ms : Vector Object fixed=false 1096 ms : ByteArray writeBoolean 1514 ms : ByteArray readBoolean
数値
uint
type uint FREQUENCY_OF_TRIAL : 50000 11 ms : Array 3 ms : Vector uint fixed=true 6 ms : Vector uint fixed=false 5 ms : Vector Object fixed=true 10 ms : Vector Object fixed=false 25 ms : ByteArray writeUnsignedInt 17 ms : ByteArray readUnsignedInt 13 ms : ByteArray writeShort 16 ms : ByteArray readShort
type uint FREQUENCY_OF_TRIAL : 5,000,000 1426 ms : Array 303 ms : Vector uint fixed=true 759 ms : Vector uint fixed=false 487 ms : Vector Object fixed=true 1417 ms : Vector Object fixed=false 1301 ms : ByteArray writeUnsignedInt 1551 ms : ByteArray readUnsignedInt 1251 ms : ByteArray writeShort 1559 ms : ByteArray readShort
Number
type Number FREQUENCY_OF_TRIAL : 50,000 38 ms : Array 4 ms : Vector Number fixed=true 26 ms : Vector Number fixed=false 20 ms : Vector Object fixed=true 24 ms : Vector Object fixed=false 28 ms : ByteArray writeUnsignedInt 16 ms : ByteArray readUnsignedInt
type Number FREQUENCY_OF_TRIAL : 5,000,000 2474 ms : Array 482 ms : Vector Number fixed=true 1342 ms : Vector Number fixed=false 1405 ms : Vector Object fixed=true 2391 ms : Vector Object fixed=false 1583 ms : ByteArray writeUnsignedInt 1551 ms : ByteArray readUnsignedInt
文字列
type String FREQUENCY_OF_TRIAL : 50,000 7 ms : Array 0 ms : Vector String fixed=true 21 ms : Vector String fixed=false 4 ms : Vector Object fixed=true 20 ms : Vector Object fixed=false 56 ms : ByteArray writeString 72 ms : ByteArray readString
type String FREQUENCY_OF_TRIAL : 5,000,000 1496 ms : Array 463 ms : Vector String fixed=true 1567 ms : Vector String fixed=false 438 ms : Vector Object fixed=true 1453 ms : Vector Object fixed=false 3125 ms : ByteArray writeString 6621 ms : ByteArray readString
非プリミティブ型
Shape
type Shape FREQUENCY_OF_TRIAL : 500000 20655 ms : create Shape 289 ms : Array 229 ms : Vector Shape fixed=true 317 ms : Vector Shape fixed=false 209 ms : Vector Object fixed=true 298 ms : Vector Object fixed=false (ByteArray はタイムアウト)
TypoLetter
FREQUENCY_OF_TRIAL : 50000 19692 ms : create TypoLetter 25 ms : Array 27 ms : Vector TypoLetter fixed=true 36 ms : Vector TypoLetter fixed=false 25 ms : Vector Object fixed=true 28 ms : Vector Object fixed=false (ByteArray はタイムアウト)
- ソース(ZIP 7.03KB)
以下、感想。
ByteArray について <使うなキケン>
とてつもない遅さに驚きました。 バイナリ直接叩いてるんだからビット演算とかバリバリ使ってて速いんだろうなぁと何の根拠もなく想像していたんですが、ものの見事に裏切られましたよ。 しかも write より read の方が遅いってのは、どういうワケやねん( Number 型のときは read の方が速いけど)。
カスタムコレクションのベースとして ByteArray は使っちゃいけん、ちゅーことやね。
Vector について <プリミティブ型を対象に厳密な状況で>
格納対象データがプリミティブ型の場合は、ちゃんと型の指定をおこないましょう、そして、第2引数は true にしましょう(つまり、格納個数を最初に把握しましょう)、ってことすね。
それにしても fixed を true にするとしないとであからさまにパフォーマンスが変わるなぁ。 fixed を true にしないと Array よりも遅くなるときがあるぞ。
で、非プリミティブ型の場合は型をちゃんと指定しても Object でも大して変わらんよ、また、第2引数を true にしてもあまり変わらんよ、って感じっすね。
Array について <オールマイティ>
格納対象がプリミティブ型のデータの場合は積極的に Vector に切り替えるべき(ただし第2引数を true にできる場合に限る)だけんども、非プリミティブ型の場合は Vector に切り替えてもたいした恩恵はなさそう、ってな感じですかねー。
結論。
オレ様が作る小物如きには Array で充分。