オーディオいじりのための最適化実験続き

前回の続き。より実践的に、とういことで、今回は「必ずleft/rightの変数に値を一度代入してからMath.random()をかける」という方針に変更。

package  
{
	import flash.display.Sprite;
	import flash.utils.ByteArray;
	import org.sazameki.audio.core.Sample;
	import flash.utils.getTimer;

	public class ByteArrayTest2 extends Sprite
	{
		
		public function ByteArrayTest2() 
		{
			var ba:ByteArray = new ByteArray();
			var ba0:ByteArray = new ByteArray();
			var ba1:ByteArray = new ByteArray();
			var ar:Array = new Array();
			var arl:Array = new Array();
			var arr:Array = new Array();
			var arl2:Array = new Array();
			var arr2:Array = new Array();
			var ar2:Array = new Array();
			var vec:Vector.<Sample>=new Vector.<Sample>();
			var vecL:Vector.<Number>=new Vector.<Number>();
			var vecR:Vector.<Number>=new Vector.<Number>();
			var VecIntR:Vector.<int>=new Vector.<int>();
			var VecIntL:Vector.<int>=new Vector.<int>();
			var i:int;
			for (i = 0; i < 44100; i++)
			{
				ba.writeFloat(Math.random());
				ba.writeFloat(Math.random());
				ba0.writeFloat(Math.random());
				ba0.writeFloat(Math.random());
				ar.push(Math.random());
				ar.push(Math.random());
				arl.push(Math.random());
				arr.push(Math.random());
				arl2.push(Math.random());
				arr2.push(Math.random());
				vec.push(new Sample(Math.random(), Math.random()));
				ar2.push(new Sample(Math.random(), Math.random()));
				vecL.push(Math.random());
				vecR.push(Math.random());
				VecIntL.push(Math.random() * 0xFFFFFFFF);
				VecIntR.push(Math.random() * 0xFFFFFFFF);
			}

			var time:int;
			var left:Number;
			var right:Number;
			var smpl:Sample;
			var k:int;
			trace("ByteArrayStart:" +(time = getTimer()) );
			for (k = 0; k < 100; k++)
			{
				ba.position = 0;
				for (i = 0; i < 44100; i++)
				{
					left = ba.readFloat();
					right = ba.readFloat();
					ba.position = ba.position - 8;
					ba.writeFloat(left*Math.random());
					ba.writeFloat(right*Math.random());
				}
			}

			trace("cost:" + (getTimer() - time));
			
			
			var read:ByteArray=ba0;
			var write:ByteArray=ba1;
			var currentReadIs0:Boolean = true;
			
			trace("ByteArray2Start:" +(time = getTimer()) );
			for (k = 0; k < 100; k++)
			{
				read.position = 0;
				write.position = 0;
				for (i = 0; i < 44100; i++)
				{
					left = read.readFloat();
					right = read.readFloat();
					
					write.writeFloat(left*Math.random());
					write.writeFloat(right*Math.random());
				}
				
				currentReadIs0 != currentReadIs0;
				if (currentReadIs0)
				{
					read = ba0;
					write = ba1;
				}else
				{
					read = ba1;
					write = ba0;
					
				}
				
			}

			trace("cost:" + (getTimer() - time));

			trace("ArrayStart:" +(time = getTimer()) );
			for (k = 0; k < 100; k++)
			{
				for (i = 0; i < 88200; i+=2)
				{
					left = ar[i];
					right = arr[i + 1];
					ar[i] = left * Math.random();
					ar[i+1] = right * Math.random();
				}
			}			
			trace("cost:" + (getTimer() - time));
			trace("Array2Start:" +(time = getTimer()) );
			for (k = 0; k < 100; k++)
			{
				for (i = 0; i < 44100; i++)
				{
					left = arl[i];
					right = arr[i];
					arl[i] = left * Math.random();
					arr[i] = left * Math.random();
				}
			}			
			trace("cost:" + (getTimer() - time));

			
		
			trace("SampleStart:" +(time = getTimer()) );
			for (k = 0; k < 100; k++)
			{
				for (i = 0; i < 44100; i++)
				{
					smpl = ar2[i];
					left = smpl.left;
					right = smpl.right;
					smpl.left = left * Math.random();
					smpl.right = right * Math.random();
				}
			}			
			
			trace("cost:" + (getTimer() - time));
			
			
			
			trace("VectorStart:" +(time = getTimer()) );
			for (k = 0; k < 100; k++)
			{
				for (i = 0; i < 44100; i++)
				{
					smpl = vec[i];
					left = smpl.left;
					right = smpl.right;
					smpl.left =  left * Math.random();
					smpl.right = right * Math.random();
				}
			}			
			
			trace("cost:" + (getTimer() - time));
			
			trace("Vector2Start:" +(time = getTimer()) );
			for (k = 0; k < 100; k++)
			{
				for (i = 0; i < 44100; i++)
				{
					left = vecL[i];
					right = vecR[i];
					vecL[i] = left * Math.random();
					vecR[i] = right * Math.random();
				}
			}			
			
			trace("cost:" + (getTimer() - time));
			
			var left2:int;
			var right2:int;
			trace("VectorInt2Start:" +(time = getTimer()) );
			for (k = 0; k < 100; k++)
			{
				for (i = 0; i < 44100; i++)
				{
					left2 = vecL[i];
					right2 = vecR[i];
					vecL[i] = left2 * Math.random();
					vecR[i] = right2 * Math.random();
				}
			}			
			
			trace("cost:" + (getTimer() - time));
			
		}
		
		
	}
	
}

結果

ByteArrayStart:1251
cost:6757
ByteArray2Start:8009
cost:5077
ArrayStart:13087
cost:5864
Array2Start:18952
cost:5208
SampleStart:24161
cost:3297
VectorStart:27459
cost:3218
Vector2Start:30678
cost:3042
VectorInt2Start:33721
cost:3093

まあ予想通りといえば予想どおりなんだけれども、特に大きな変化は見られず。

  • ついでに、ByteArrayのposition変えるコストがどんなもんなのかと思って、試みに二つのByteArrayで読み込み/書き込みを相互に変えるのもやってみた(二つ目)けどそこまで大きな改善は見られず。
  • Vector.も試してみた(一番最後)けど目立った差はなし。となるとやはりNumber型のほうが扱いやすいと思われる。
  • こちらの記事を見てるとどうもByteArrayかVectorをPixelBenderでの処理が可能?、みたいなことが書いてあって、これがオーディオ処理でも活用できるのかPixleBenderのリファレンス見ててもよくわからなかった。ので、とりあえずコード待ち。ただ何にせよVector使っといたほうが後々よさそうなのは確か。

という諸々を総合して、素直にVector.使っとくのがよさそうなので、その方向で遊び始めることにしました。