Vector3D
Vector3Dの関数と同じ処理の関数を10万回実行した時の処理時間(ミリ秒)
今回はnew Vector3D(Math.random(),Math.random(),Math.random());で
10万個のVector3Dを生成して計測。
keim_at_Siの突っ込みを参考にしたけど、コレで合ってるかな。
同じ機能の関数を作った方が早いみたい。
Vctr3D.nearEquals()は暫定版。
また、除算などの場合、小数の最後の桁の数字が正確には一致しないことがある。
さんざん検証したが、実際の制作ではほぼ意味がないレベルの最適化。
Flashにおいて10万頂点数ってまずないし、それでも数十mm/secの違いしかない。
多くても数百〜千頂点程度だから、30fpsの場合1秒あたり3万頂点数。
30フレームあたり20mm/secの最適化ができたとしても、
29.0fpsだったものが29.6fpsになるくらいのもの。
基本的に描画の段階がボトルネックになっているので描画オブジェクトを減らしたり、
アルファを使うべきか見直したり、小さくした方がはるかに最適化の効果を得られるはず。
それらを一通りやった後だったら、気休め程度にはいいかも、、、。
MacBookPro2.4Gh,OSX 10.5.6
_Vector3D_0:39:length
_Vctr3D_0:23:Vctr3D.length()
_Vector3D_1:25:lengthSquared
_Vctr3D_1:10:Vctr3D.lengthSquared()
_Vector3D_2:76:add()
_Vctr3D_2:65:Vctr3D.add()
_Vector3D_3:95:angleBetween()
_Vctr3D_3:57:Vctr3D.angleBetween()
_Vector3D_4:75:clone()
_Vctr3D_4:65:Vctr3D.clone()
_Vector3D_5:79:crossProduct()
_Vctr3D_5:65:Vctr3D.crossProduct()
_Vector3D_6:23:decrementBy()
_Vctr3D_6:14:Vctr3D.decrementBy()
_Vector3D_7:105:distance()
/**
* Copyright umhr ( http://wonderfl.net/user/umhr )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/lFH0
*/
/**
Vector3Dの関数と同じ処理の関数を10万回実行した時の処理時間(ミリ秒)
今回はnew Vector3D(Math.random(),Math.random(),Math.random());で
10万個のVector3Dを生成して計測。
keim_at_Siの突っ込みを参考にしたけど、コレで合ってるかな。
同じ機能の関数を作った方が早いみたい。
Vctr3D.nearEquals()は暫定版。
また、除算などの場合、小数の最後の桁の数字が正確には一致しないことがある。
さんざん検証したが、実際の制作ではほぼ意味がないレベルの最適化。
Flashにおいて10万頂点数ってまずないし、それでも数十mm/secの違いしかない。
多くても数百〜千頂点程度だから、30fpsの場合1秒あたり3万頂点数。
30フレームあたり20mm/secの最適化ができたとしても、
29.0fpsだったものが29.6fpsになるくらいのもの。
基本的に描画の段階がボトルネックになっているので描画オブジェクトを減らしたり、
アルファを使うべきか見直したり、小さくした方がはるかに最適化の効果を得られるはず。
それらを一通りやった後だったら、気休め程度にはいいかも、、、。
MacBookPro2.4Gh,OSX 10.5.6
_Vector3D_0:39:length
_Vctr3D_0:23:Vctr3D.length()
_Vector3D_1:25:lengthSquared
_Vctr3D_1:10:Vctr3D.lengthSquared()
_Vector3D_2:76:add()
_Vctr3D_2:65:Vctr3D.add()
_Vector3D_3:95:angleBetween()
_Vctr3D_3:57:Vctr3D.angleBetween()
_Vector3D_4:75:clone()
_Vctr3D_4:65:Vctr3D.clone()
_Vector3D_5:79:crossProduct()
_Vctr3D_5:65:Vctr3D.crossProduct()
_Vector3D_6:23:decrementBy()
_Vctr3D_6:14:Vctr3D.decrementBy()
_Vector3D_7:105:distance()
_Vctr3D_7:27:Vctr3D.distance()
_Vector3D_8:27:dotProduct()
_Vctr3D_8:14:Vctr3D.dotProduct()
_Vector3D_9:24:equals()
_Vctr3D_9:15:Vctr3D.equals()
_Vector3D_10:23:incrementBy()
_Vctr3D_10:14:Vctr3D.incrementBy()
_Vector3D_11:28:nearEquals()
_Vctr3D_11:26:Vctr3D.nearEquals()
_Vector3D_12:22:negate()
_Vctr3D_12:11:Vctr3D.negate()
_Vector3D_13:53:normalize()
_Vctr3D_13:27:Vctr3D.normalize()
_Vector3D_14:22:project()
_Vctr3D_14:15:Vctr3D.project()
_Vector3D_15:26:scaleBy()
_Vctr3D_15:14:Vctr3D.scaleBy()
_Vector3D_16:75:subtract()
_Vctr3D_16:64:Vctr3D.subtract()
_Vector3D_17:1760:toString()
_Vctr3D_17:1753:Vctr3D.ToString()
_a99:9:対照用に0を返すだけの関数
*/
package {
import flash.display.Sprite;
import flash.geom.Vector3D;
import flash.text.TextField;
public class vecor3Dtest extends Sprite {
public var _a:Vector.<Vector3D>=new Vector.<Vector3D>(100000,true);
public var _b:Vector.<Vector3D>=new Vector.<Vector3D>(100000,true);
private var Vctr3D:Vctr3DClass = new Vctr3DClass();
public function vecor3Dtest():void {
var tf1:TextField = new TextField();
tf1.width=stage.stageWidth/2;
tf1.wordWrap = true;
var tf2:TextField = new TextField();
tf2.width=tf2.x=stage.stageWidth/2;
tf1.height=tf2.height=stage.stageHeight;
stage.addChild(tf1);
stage.addChild(tf2);
for (var i:int=0; i<100000; i++) {
_a[i]=new Vector3D(Math.random(),Math.random(),Math.random(),Math.random());
_b[i]=new Vector3D(Math.random(),Math.random(),Math.random(),Math.random());
}
var _str1:String = new String();
var _str2:String = new String();
_str1="Vector3Dの関数と同じ処理の関数を10万回実行した時の処理時間(ミリ秒)\r";
//順番による影響を減らすために、一度実行。一番目は遅くなるっぽい
benchMarkj(_Vector3D_0);
benchMarkj(_Vctr3D_0);
benchMarkj(_Vector3D_1);
benchMarkj(_Vctr3D_1);
benchMarkj(_Vector3D_2);
benchMarkj(_Vctr3D_2);
benchMarkj(_Vector3D_3);
benchMarkj(_Vctr3D_3);
benchMarkj(_Vector3D_4);
benchMarkj(_Vctr3D_4);
benchMarkj(_Vector3D_5);
benchMarkj(_Vctr3D_5);
benchMarkj(_Vector3D_6);
benchMarkj(_Vctr3D_6);
benchMarkj(_Vector3D_7);
benchMarkj(_Vctr3D_7);
benchMarkj(_Vector3D_8);
benchMarkj(_Vctr3D_8);
benchMarkj(_Vector3D_9);
benchMarkj(_Vctr3D_9);
benchMarkj(_Vector3D_10);
benchMarkj(_Vctr3D_10);
benchMarkj(_Vector3D_11);
benchMarkj(_Vctr3D_11);
benchMarkj(_Vector3D_12);
benchMarkj(_Vctr3D_12);
benchMarkj(_Vector3D_13);
benchMarkj(_Vctr3D_13);
benchMarkj(_Vector3D_14);
benchMarkj(_Vctr3D_14);
benchMarkj(_Vector3D_15);
benchMarkj(_Vctr3D_15);
benchMarkj(_Vector3D_16);
benchMarkj(_Vctr3D_16);
benchMarkj(_Vector3D_17);
benchMarkj(_Vctr3D_17);
benchMarkj(_a99);
_str1+="_Vector3D_0:"+benchMarkj(_Vector3D_0)+":length\r";//39
_str1+="_Vctr3D_0:"+benchMarkj(_Vctr3D_0)+":Vctr3D.length()\r";//23
_str1+="_Vector3D_1:"+benchMarkj(_Vector3D_1)+":lengthSquared\r";//25
_str1+="_Vctr3D_1:"+benchMarkj(_Vctr3D_1)+":Vctr3D.lengthSquared()\r";//10
_str1+="_Vector3D_2:"+benchMarkj(_Vector3D_2)+":add()\r";//76
_str1+="_Vctr3D_2:"+benchMarkj(_Vctr3D_2)+":Vctr3D.add()\r";//65
_str1+="_Vector3D_3:"+benchMarkj(_Vector3D_3)+":angleBetween()\r";//95
_str1+="_Vctr3D_3:"+benchMarkj(_Vctr3D_3)+":Vctr3D.angleBetween()\r";//57
_str1+="_Vector3D_4:"+benchMarkj(_Vector3D_4)+":clone()\r";//75
_str1+="_Vctr3D_4:"+benchMarkj(_Vctr3D_4)+":Vctr3D.clone()\r";//65
_str1+="_Vector3D_5:"+benchMarkj(_Vector3D_5)+":crossProduct()\r";//79
_str1+="_Vctr3D_5:"+benchMarkj(_Vctr3D_5)+":Vctr3D.crossProduct()\r";//65
_str1+="_Vector3D_6:"+benchMarkj(_Vector3D_6)+":decrementBy()\r";//23
_str1+="_Vctr3D_6:"+benchMarkj(_Vctr3D_6)+":Vctr3D.decrementBy()\r";//14
_str1+="_Vector3D_7:"+benchMarkj(_Vector3D_7)+":distance()\r";//105
_str1+="_Vctr3D_7:"+benchMarkj(_Vctr3D_7)+":Vctr3D.distance()\r";//27
_str1+="_Vector3D_8:"+benchMarkj(_Vector3D_8)+":dotProduct()\r";//27
_str1+="_Vctr3D_8:"+benchMarkj(_Vctr3D_8)+":Vctr3D.dotProduct()\r";//14
_str1+="_Vector3D_9:"+benchMarkj(_Vector3D_9)+":equals()\r";//24
_str1+="_Vctr3D_9:"+benchMarkj(_Vctr3D_9)+":Vctr3D.equals()\r";//15
_str2+="_Vector3D_10:"+benchMarkj(_Vector3D_10)+":incrementBy()\r";//23
_str2+="_Vctr3D_10:"+benchMarkj(_Vctr3D_10)+":Vctr3D.incrementBy()\r";//14
_str2+="_Vector3D_11:"+benchMarkj(_Vector3D_11)+":nearEquals()\r";//28
_str2+="_Vctr3D_11:"+benchMarkj(_Vctr3D_11)+":Vctr3D.nearEquals()\r";//26
_str2+="_Vector3D_12:"+benchMarkj(_Vector3D_12)+":negate()\r";//22
_str2+="_Vctr3D_12:"+benchMarkj(_Vctr3D_12)+":Vctr3D.negate()\r";//11
_str2+="_Vector3D_13:"+benchMarkj(_Vector3D_13)+":normalize()\r";//53
_str2+="_Vctr3D_13:"+benchMarkj(_Vctr3D_13)+":Vctr3D.normalize()\r";//27
_str2+="_Vector3D_14:"+benchMarkj(_Vector3D_14)+":project()\r";//22
_str2+="_Vctr3D_14:"+benchMarkj(_Vctr3D_14)+":Vctr3D.project()\r";//15
_str2+="_Vector3D_15:"+benchMarkj(_Vector3D_15)+":scaleBy()\r";//26
_str2+="_Vctr3D_15:"+benchMarkj(_Vctr3D_15)+":Vctr3D.scaleBy()\r";//14
_str2+="_Vector3D_16:"+benchMarkj(_Vector3D_16)+":subtract()\r";//75
_str2+="_Vctr3D_16:"+benchMarkj(_Vctr3D_16)+":Vctr3D.subtract()\r";//64
_str2+="_Vector3D_17:"+benchMarkj(_Vector3D_17)+":toString()\r";//1760
_str2+="_Vctr3D_17:"+benchMarkj(_Vctr3D_17)+":Vctr3D.ToString()\r";//1753
_str2+="_a99:"+benchMarkj(_a99)+":対照用に0を返すだけの関数\r";//9
tf1.text=_str1;
tf2.text=_str2;
}
//10万回関数を実行して、かかった時間をtrace
private function benchMarkj(_fn:Function):int {
var time:Number = (new Date()).getTime();
_fn(100000);
return (new Date()).getTime() - time;
}
private function _Vector3D_0(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].length;
}
}
private function _Vctr3D_0(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.length(_a[i]);
}
}
private function _Vector3D_1(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].lengthSquared;
}
}
private function _Vctr3D_1(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.lengthSquared(_a[i]);
}
}
private function _Vector3D_2(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].add(_b[i]);
}
}
private function _Vctr3D_2(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.add(_a[i],_b[i]);
}
}
private function _Vector3D_3(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vector3D.angleBetween(_a[i],_b[i]);
}
}
private function _Vctr3D_3(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.angleBetween(_a[i],_b[i]);
}
}
private function _Vector3D_4(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].clone();
}
}
private function _Vctr3D_4(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.clone(_a[i]);
}
}
private function _Vector3D_5(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].crossProduct(_b[i]);
}
}
private function _Vctr3D_5(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.crossProduct(_a[i],_b[i]);
}
}
private function _Vector3D_6(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].decrementBy(_b[i]);
}
}
private function _Vctr3D_6(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.decrementBy(_a[i],_b[i]);
}
}
private function _Vector3D_7(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vector3D.distance(_a[i],_b[i]);
}
}
private function _Vctr3D_7(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.distance(_a[i],_b[i]);
}
}
private function _Vector3D_8(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].dotProduct(_b[i]);
}
}
private function _Vctr3D_8(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.dotProduct(_a[i],_b[i]);
}
}
private function _Vector3D_9(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].equals(_b[i],true);
}
}
private function _Vctr3D_9(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.equals(_a[i],_b[i],true);
}
}
private function _Vector3D_10(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].incrementBy(_b[i]);
}
}
private function _Vctr3D_10(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.incrementBy(_a[i],_b[i]);
}
}
private function _Vector3D_11(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].nearEquals(_b[i],1,true);
}
}
private function _Vctr3D_11(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.nearEquals(_a[i],_b[i],1,true);
}
}
private function _Vector3D_12(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].negate();
}
}
private function _Vctr3D_12(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.negate(_a[i]);
}
}
private function _Vector3D_13(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].normalize();
}
}
private function _Vctr3D_13(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.normalize(_a[i]);
}
}
private function _Vector3D_14(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].project();
}
}
private function _Vctr3D_14(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.project(_a[i]);
}
}
private function _Vector3D_15(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].scaleBy(3.1);
}
}
private function _Vctr3D_15(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.scaleBy(_a[i],3.1);
}
}
private function _Vector3D_16(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].subtract(_b[i]);
}
}
private function _Vctr3D_16(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.subtract(_a[i],_b[i]);
}
}
private function _Vector3D_17(n:uint):void {
for (var i:int = 0; i < n; i++) {
_a[i].toString();
}
}
private function _Vctr3D_17(n:uint):void {
for (var i:int = 0; i < n; i++) {
Vctr3D.ToString(_a[i]);
}
}
private function _a99(n:uint):void {
for (var i:int = 0; i < n; i++) {
zero();
}
}
private function zero():Number {
return 0;
}
}
}
import flash.display.Sprite;
class Vctr3DClass extends Sprite {
import flash.geom.Vector3D;
public function length(_a:Vector3D):Number {
return Math.sqrt(_a.x*_a.x+_a.y*_a.y+_a.z*_a.z);
}
public function lengthSquared(_a:Vector3D):Number {
return _a.x*_a.x+_a.y*_a.y+_a.z*_a.z;
}
public function add(_a:Vector3D,_b:Vector3D):Vector3D {
return new Vector3D(_a.x+_b.x,_a.y+_b.y,_a.z+_b.z);
}
public function angleBetween(_a:Vector3D,_b:Vector3D):Number {
return Math.acos((_a.x*_b.x+_a.y*_b.y+_a.z*_b.z)/(Math.sqrt(_a.x*_a.x+_a.y*_a.y+_a.z*_a.z)*Math.sqrt(_b.x*_b.x+_b.y*_b.y+_b.z*_b.z)));
}
public function clone(_a:Vector3D):Vector3D {
return new Vector3D(_a.x,_a.y,_a.z,_a.w);
}
public function isHiddenCrossProduct(_a:Vector3D,_b:Vector3D):Boolean {
return _a.x*_b.y-_a.y*_b.x > 0;
}
public function crossProduct(_a:Vector3D,_b:Vector3D):Vector3D {
return new Vector3D(_a.y*_b.z-_a.z*_b.y,_a.z*_b.x-_a.x*_b.z,_a.x*_b.y-_a.y*_b.x,1);
}
public function decrementBy(_a:Vector3D,_b:Vector3D):void {
_a.x-=_b.x;
_a.y-=_b.y;
_a.z-=_b.z;
}
public function distance(_a:Vector3D,_b:Vector3D):Number {
return Math.sqrt((_a.x-_b.x)*(_a.x-_b.x)+(_a.y-_b.y)*(_a.y-_b.y)+(_a.z-_b.z)*(_a.z-_b.z));
}
public function dotProduct(_a:Vector3D,_b:Vector3D):Number {
return _a.x*_b.x+_a.y*_b.y+_a.z*_b.z;
}
public function equals(_a:Vector3D,_b:Vector3D,_is:Boolean = false):Boolean {
return _a.x == _b.x && _a.y == _b.y && _a.z == _b.z && (!_is || _a.w == _b.w);
}
public function incrementBy(_a:Vector3D,_b:Vector3D):void {
_a.x+=_b.x;
_a.y+=_b.y;
_a.z+=_b.z;
}
public function nearEquals(_a:Vector3D,_b:Vector3D,_d:Number,_is:Boolean = false):Boolean {
return Math.abs(_a.x - _b.x) < _d && Math.abs(_a.y - _b.y) < _d && Math.abs(_a.z - _b.z) < _d && (!_is || Math.abs(_a.w - _b.w) < _d);
}
public function negate(_a:Vector3D):void {
_a.x = -_a.x;
_a.y = -_a.y;
_a.z = -_a.z;
}
public function normalize(_a:Vector3D):Number {
var _len:Number = Math.sqrt(_a.x*_a.x+_a.y*_a.y+_a.z*_a.z);
_a.x /= _len;
_a.y /= _len;
_a.z /= _len;
return _len;
}
public function project(_a:Vector3D):void {
var _w:Number = _a.w;
_a.x /= _w;
_a.y /= _w;
_a.z /= _w;
}
public function scaleBy(_a:Vector3D,_s:Number):void {
_a.x *= _s;
_a.y *= _s;
_a.z *= _s;
}
public function subtract(_a:Vector3D,_b:Vector3D):Vector3D {
return new Vector3D(_a.x-_b.x,_a.y-_b.y,_a.z-_b.z);
}
public function ToString(_a:Vector3D):String {
return "Vector3D("+_a.x+", "+_a.y+", "+_a.z+")";
}
}