VectorはArrayより早い


VectorはArrayより早いAS3,FlashPlayer10では、Arrayに良く似たVectorという配列を管理するクラスが追加された。制約がある代わりに早いというのが特徴。さて、どれくらい早いのだろうか?

◆設問
↓「Vectorインスタンスを使うとArrayよりもずっと高速です。」っていうけど どれくらい高速なのだろう??
http://www.fumiononaka.com/TechNotes/Flash/FN0810001.html
と思ったのでベンチマークテスト。

◆内容
Array(_a)とVector(_v)の比較と
0:長さの指定無し
1:長さの指定あり
2:入れる数字を型指定
を1000万回行う

◆結果
1000万回関数を実行して、かかった時間(mm秒)
MAC 10,0,2,54での実行結果

Array+長さの指定無し:601
Array+長さの指定あり:577
Array+長さ+型指定あり:768
Vector+長さの指定無し:522
Vector+長さの指定あり:168
Vector+長さ+型指定あり:210

噂通りVectorで長さを指定すると早かった。
Arrayで長さを指定した時に比べて1/4ぐらいの早さ。

◆考察
確かに早いんだけど、1000万回でやっと、0.4秒の差。 通常の使用でArrayの計算時間がボトルネックになるってことはほぼ無い。3Dの座標を管理するにしても、普通はBitmapやシェイプの描画の方が律速段階になっているはず。

恐らくVectorだけでどうとかよりも、他の関数で使うための道具としての高速版ということだと思う。具体的にはsinやpowの変換テーブルとして使う場合だ。ただ、それでも全体として処理が一気に早くなる、ってことは無いと思うけど。

◆動作確認

[sourcecode language=”as3″]
/*
CS4のAS3.0
//なんで、3.1じゃなくて、3.0なのだろう。
//何のための「.0」なのだろう??

◆設問
↓「Vectorインスタンスを使うとArrayよりもずっと高速です。」っていうけど
どれくらい高速なのだろう??
http://www.fumiononaka.com/TechNotes/Flash/FN0810001.html
と思ったのでベンチマークテスト。

◆内容
Array(_a)とVector(_v)の比較と
0:長さの指定無し
1:長さの指定あり
2:入れる数字を型指定
を1000万回行う

◆結果
1000万回関数を実行して、かかった時間(mm秒)
MAC 10,0,2,54での実行結果

Array+長さの指定無し:601
Array+長さの指定あり:577
Array+長さ+型指定あり:768
Vector+長さの指定無し:522
Vector+長さの指定あり:168
Vector+長さ+型指定あり:210

噂通りVectorで長さを指定すると早かった。
Arrayで長さを指定した時に比べて1/4ぐらいの早さ。

◆考察
確かに早いんだけど、1000万回でやっと、0.4秒の差だよ。
Arrayの計算時間がボトルネックになってたことなんか、
3Dを遊びで作ったのを含めてもほぼ無いからなーw

もちろん早くなることに越したことは無いけど。
高負荷の物理計算とか、画像の各ピクセルに対して処理をする、
とかで使うと力が発揮されるのかな。

*/

package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.system.Capabilities;
public class Main extends Sprite {
public function Main() {

//txtに内容を入れ込む
var txt:String="1000万回関数を実行して、かかった時間(mm秒)n";
txt+=Capabilities.version+"での実行結果nn";

//順番による差がなるべくでないようにとりあえず100回ずつ実行
benchMarkj(_a0,100);
benchMarkj(_a1,100);
benchMarkj(_a2,100);
benchMarkj(_v0,100);
benchMarkj(_v1,100);
benchMarkj(_v2,100);

//本番
txt+="Array+長さの指定無し:"+benchMarkj(_a0,10000000)+"n";
txt+="Array+長さの指定あり:"+benchMarkj(_a1,10000000)+"n";
txt+="Array+長さ+型指定あり:"+benchMarkj(_a2,10000000)+"n";
txt+="Vector+長さの指定無し:"+benchMarkj(_v0,10000000)+"n";
txt+="Vector+長さの指定あり:"+benchMarkj(_v1,10000000)+"n";
txt+="Vector+長さ+型指定あり:"+benchMarkj(_v2,10000000)+"n";

//テキストフィールドを作りtxtを流し込み。
var tf:TextField = new TextField();
tf.width=stage.stageWidth;
tf.height=stage.stageHeight;
tf.wordWrap=true;
stage.addChild(tf);
tf.text=txt;

//1000万回関数を実行して、かかった時間
function benchMarkj(_fn:Function,count:int):Number {
var time:Number = (new Date()).getTime();
_fn(count);
return (new Date()).getTime() – time;
}

//Array+長さの指定無し
function _a0(n:uint):void {
var ar:Array = new Array();
for (var i:int = 0; i < n; i++) {
ar[i]=3.0;
}
}

//Array+長さの指定あり
function _a1(n:uint):void {
var ar:Array=new Array(n);
for (var i:int = 0; i < n; i++) {
ar[i]=3.0;
}
}

//Array+長さ+型指定あり
function _a2(n:uint):void {
var ar:Array=new Array(n);
for (var i:int = 0; i < n; i++) {
ar[i]=Number(3.0);
}
}

//Vector+長さの指定無し
function _v0(n:uint):void {
var ar:Vector.<Number> = new Vector.<Number>();
for (var i:int = 0; i < n; i++) {
ar[i]=3.0;
}
}

//Vector+長さの指定あり
function _v1(n:uint):void {
var ar:Vector.<Number>=new Vector.<Number>(n);
for (var i:int = 0; i < n; i++) {
ar[i]=3.0;
}
}

//Vector+長さ+型指定あり
function _v2(n:uint):void {
var ar:Vector.<Number>=new Vector.<Number>(n);
for (var i:int = 0; i < n; i++) {
ar[i]=Number(3.0);
}
}
}
}
}
[/sourcecode]