Dead Code Preservation :: Archived AS3 works from wonderfl.net

xorshiftのテスト

XorShiftのテスト
本来32bitのはずなのに31bitしかないというできそこない
Get Adobe Flash player
by NiFiZ 08 May 2009
// 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)) );
    }
  
}