// XorShiftのテスト
// 本来32bitのはずなのに31bitしかないというできそこない
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*;
import flash.text.TextField;
import frocessing.color.ColorHSV;
[SWF(width="465", height="465", backgroundColor="0x000000")]
public class XorShiftTest extends Sprite {
public function XorShiftTest() {
init();
}
private function init():void
{
var scr:BitmapData = new BitmapData(465, 465, false, 0);
parent.addChild( new Bitmap(scr));
scr.lock();
scr.fillRect( new Rectangle(0,0,465,465),0x000000 );
var xos:XorShift128 = new XorShift128();
xos.setSeed((new Date()).getTime());
for( var i:int =0; i < 10000000; ++ i )
{
var x:int = xos.get32() % (465/2);
var y:int = xos.get32() % 465;
var col:uint = scr.getPixel(x,y);
var b:uint = col & 0x0000FF;
++b;
col = b << 16 | b << 8 | b;
scr.setPixel(x,y,col);
}
var rnd:Function = Math.random;
for( i =0; i < 10000000; ++ i )
{
x = rnd() * (465/2)+465/2;
y = rnd() * 465;
col = scr.getPixel(x,y);
b = col & 0x0000FF;
++b;
col = b << 16 | b << 8 | b;
scr.setPixel(x,y,col);
}
scr.unlock();
// とりあえず時間を計測してみよう
var time:Number;
time = (new Date()).getTime();
var n1:Number=0;
for( i =0; i < 10000000; ++ i )
{
n1 += xos.get32()/0x7FFFFFFF ;
}
var time1:Number = (new Date()).getTime() - time;
time = (new Date()).getTime();
var n2:Number=0;
for( i =0; i < 10000000; ++ i )
{
n2 += rnd();
}
var time2:Number = (new Date()).getTime() - time;
var textF:TextField = new TextField();
textF.width = 465;
textF.height = 465;
stage.addChild(textF);
var str:String = new String();
str = "XorShiftと標準のMath.randomを比較してみた\r ちなみに画面左半分がXorShiftで生成した図で、右半分がMath.randomを使った図。\r線とかぐらい引っ張っとけよすごくわかりづらい、と思った。\r";
str += "XorShiftとMath.random()をそれぞれ10000000回実行したときの処理時間を計測\r";
str += "XorShiftの速度" + time1 + "ms" + " 平均:" + n1/10000000 + "\r";
str += "Math.randomの速度" + time2 + "ms" + " 平均:" + n2/10000000 +"\r";
str += "結構速い気がする";
textF.text = str;
textF.textColor = 0xFFFFFF;
}
}
}
class XorShift128
{
private var a:uint;
private var b:uint;
private var c:uint;
private var d:uint;
public function XorShift128()
{
setSeed(0);
}
// 種を与える
public function setSeed( seed:uint ):void
{
a=seed=1812433253*(seed^(seed>>30))+0;
b=seed=1812433253*(seed^(seed>>30))+1;
c=seed=1812433253*(seed^(seed>>30))+2;
d=seed=1812433253*(seed^(seed>>30))+3;
}
// 整数乱数を生成
// get32という名前の癖に31bitしかない。
// c++だとちゃんと動いたんだけどなぁ。
public function get32():uint
{
var t:uint = (a^(a<<11));
a=b; b=c; c=d;
return( d=(d^(d>>19))^(t^(t>>8)) );
}
}