frocessingでは、Matrixを拡張してFMatrix2Dというクラスをつくっているのですが、その過程でどうもオリジナルの matrix.scale() と Matrix.rotate() が遅いんじゃないかと思いまして、以下試してみたものです。
とりあえずテスト用につくったもので、オリジナル(ori)と scale,translate,rotateをoverrideして実装しなおしたもの(ext)を、それぞれfor文でまわしたものです。影響が出そうな、createBox, createGradientBox についても比較しています。それぞれ10万回実行しています。
自分の環境では、translateは大体同じだけど、scale と rotate 及び影響が出ていると思われる box系で随分処理時間に差が出ています。どうでしょうか?
実際には10万回なんて実行しないので、現実的には差がないように思えますが、とりあえずメモということで。
以下実装し直した TestMatrix と 上のテストで使用したスクリプトです。
TestMatrix.as
package{ import flash.geom.Matrix; public class TestMatrix extends Matrix { public function TestMatrix( a_:Number=1, b_:Number=0, c_:Number=0, d_:Number=1, tx_:Number=0, ty_:Number=0) { super( a_, b_, c_, d_, tx_, ty_ ); } override public function translate( dx:Number, dy:Number ):void { //(1,0,0,1,dx,dy) tx += dx; ty += dy; } override public function scale( sx:Number, sy:Number ):void { //(sx,0,0,sx,0,0) a *= sx; b *= sy; c *= sx; d *= sy; tx *= sx; ty *= sy; } override public function rotate( angle:Number ):void { //(c, s, -s, c, 0, 0) var sin:Number = Math.sin(angle); var cos:Number = Math.cos(angle); var n11:Number = a * cos - b * sin; var n12:Number = a * sin + b * cos; var n21:Number = c * cos - d * sin; var n22:Number = c * sin + d * cos; var n31:Number = tx * cos - ty * sin; var n32:Number = tx * sin + ty * cos; a = n11; b = n12; c = n21; d = n22; tx = n31; ty = n32; } } }
テストコード
//ベタなテストですいません
//out_txtはTextFieldです
var n:int = 50000;
var t:int;
var i:int;
var fmt:TestMatrix = new TestMatrix( 1, 2, 3, 4, 5, 6 );
var mt:Matrix = new Matrix( 1, 2, 3, 4, 5, 6 );
//---------------------------------------------
out_txt.appendText( "[SCALE]");
t = getTimer();
for( i=0; i<n; i++ )
{
mt.scale( 10, 10 ); mt.scale( 0.1,0.1 );
}
out_txt.appendText( "\n ori: " + (getTimer()-t).toString() );
t = getTimer();
for( i=0; i<n; i++ )
{
fmt.scale(10,10); fmt.scale(0.1,0.1);
}
out_txt.appendText( " ext: " + (getTimer()-t).toString() );
//---------------------------------------------
out_txt.appendText( "\n[TRANSLATE]");
t = getTimer();
for( i=0; i<n; i++ )
{
mt.translate( 10, 10 ); mt.translate( -10,-10 );
}
out_txt.appendText( "\n ori: " + (getTimer()-t).toString() );
t = getTimer();
for( i=0; i<n; i++ )
{
fmt.translate(10,10); fmt.translate(-10,-10);
}
out_txt.appendText( " ext: " + (getTimer()-t).toString() );
//---------------------------------------------
out_txt.appendText( "\n[ROTATE]");
t = getTimer();
for( i=0; i<n; i++ )
{
mt.rotate( 1.5 ); mt.rotate( -1.5 );
}
out_txt.appendText( "\n ori: " + (getTimer()-t).toString() );
t = getTimer();
for( i=0; i<n; i++ )
{
fmt.rotate(1.5); fmt.rotate(-1.5);
}
out_txt.appendText( " ext: " + (getTimer()-t).toString() );
//---------------------------------------------
out_txt.appendText( "\n[CREATE_BOX]");
t = getTimer();
for( i=0; i<n; i++ )
{
mt.createBox( 10, 10, 1, 1, 1 );
mt.createBox( 0.1, 0.1, -1, -1, -1 );
}
out_txt.appendText( "\n ori: " + (getTimer()-t).toString() );
t = getTimer();
for( i=0; i<n; i++ )
{
fmt.createBox( 10, 10, 1, 1, 1 );
fmt.createBox( 0.1, 0.1, -1, -1, -1 );
}
out_txt.appendText( " ext: " + (getTimer()-t).toString() );
//---------------------------------------------
out_txt.appendText( "\n[CREATE_GRADIENT_BOX]");
t = getTimer();
for( i=0; i<n; i++ )
{
mt.createGradientBox( 10, 10, 1, 1, 1 );
mt.createGradientBox( 0.1, 0.1, -1, -1, -1 );
}
out_txt.appendText( "\n ori: " + (getTimer()-t).toString() );
t = getTimer();
for( i=0; i<n; i++ )
{
fmt.createGradientBox( 10, 10, 1, 1, 1 );
fmt.createGradientBox( 0.1, 0.1, -1, -1, -1 );
}
out_txt.appendText( " ext: " + (getTimer()-t).toString() );
テストの方法が微妙な気がしますが、いいベンチマークの方法があったら知りたい…