Integer math optimization test

by yonatan
Integer math optimization test - http://jpauclair.net/2010/03/15/flash-asm/
♥2 | Line 132 | Modified 2010-04-11 16:41:01 | MIT License
play

ActionScript3 source code

/**
 * Copyright yonatan ( http://wonderfl.net/user/yonatan )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/eAZv
 */

// Integer math optimization test - http://jpauclair.net/2010/03/15/flash-asm/

package {
    import flash.display.*;
    import flash.text.*;
    import flash.utils.*;
    import net.hires.debug.Stats;

    public class FlashTest extends Sprite {
        private static const W:uint = 1000;
        private static const H:uint = 1000;

        private var canvas:BitmapData = new BitmapData(W,H,false);
        private var startX:int;
        private var startY:int;
        private var stepX:int;
        private var stepY:int;
        private var pixelX:int;
        private var pixelY:int;

        private var calc:Function;
        private var tf:TextField;

        public function FlashTest() {
            // addChild(new Bitmap(canvas)).y=100;
            // addChild(new Stats).x=400;
            addChild(tf = new TextField);
            tf.width = tf.height = 465;

            startX = -1.5 * (1 << 13);
            startY = -1 * (1 << 13);
            stepX = 2/W * (1 << 13);
            stepY = 2/H * (1 << 13);
            
            var outx:uint = 0;

            var start:Number;
            for each(var name:String in ["calc1", "calc2", "calc3", "calc4", "calc5"]) {
                calc = this[name];
                start = getTimer();
                render();
                tf.appendText(name + " time: " + (getTimer() - start) + "\n");
                var bmp:Bitmap = new Bitmap(canvas.clone());
                bmp.height = bmp.width = 80;
                bmp.x = outx;
                bmp.y = 300;
                outx += 90;
                addChild(bmp);
            }
            
            // addEventListener("enterFrame", render);
        }

        private function render(e:* = null):void {
            canvas.lock()
            for(pixelY=0, cy=startY; pixelY<H; pixelY++, cy += stepY) {
                for(pixelX=0, cx=startX; pixelX<W; pixelX++, cx += stepX) {
                    calc();
                    // iter &= 0xff; // make inside 0
                    canvas.setPixel(pixelX, pixelY, iter * 0x10101);
                }
            }
            canvas.unlock();
        }

        private var cx:int;
        private var cy:int;
        private var zx:int;
        private var zy:int;
        private var xx:int;
        private var yy:int;
        private var iter:uint;

        private function calc1():void { // naive version
            xx = yy = iter = 0;
            zx = cx;
            zy = cy;
            for(; xx+yy < (4 << 13) && iter < 0x100; iter++) {
                xx = zx*zx >> 13;
                yy = zy*zy >> 13;
                zy = (zx*zy >> 12) + cy;
                zx = xx-yy + cx;
            }
        }

        private function calc2():void { // no int casts, separate lines
            xx = yy = iter = 0;
            zx = cx;
            zy = cy;
            for(; xx+yy < (4 << 13) && iter < 0x100; iter++) {
                xx = zx*zx;
                xx >>= 13;
                yy = zy*zy;
                yy >>= 13;
                zy = zx*zy;
                zy >>= 12;
                zy += cy; // zy = 2*zx*zy + cy
                zx = xx-yy;
                zx += cx; // zx = zx*zx - zy*zy + cx
            }
        }

        private function calc3():void { // explicit int casts
            xx = yy = iter = 0;
            zx = cx;
            zy = cy;
            for(; int(xx+yy) < (4 << 13) && iter < 0x100; iter++) {
                xx = int(zx*zx) >> 13;
                yy = int(zy*zy) >> 13;
                zy = int(int(zx*zy) >> 12) + cy; // zy = 2*zx*zy + cy
                zx = int(xx-yy) + cx; // zx = zx*zx - zy*zy + cx
            }
        }

        private function calc4():void { // explicit int casts, local vars
            var zx:int;
            var zy:int;
            var xx:int;
            var yy:int;
            var iter:int;

            xx = yy = iter = 0;
            zx = cx;
            zy = cy;
            for(; int(xx+yy) < (4 << 13) && iter < 0x100; iter++) {
                xx = int(zx*zx) >> 13;
                yy = int(zy*zy) >> 13;
                zy = int(int(zx*zy) >> 12) + cy; // zy = 2*zx*zy + cy
                zx = int(xx-yy) + cx; // zx = zx*zx - zy*zy + cx
            }

            this.iter = iter;
        }

        private function calc5():void { // explicit int casts, local reads make it slower???
            var zx:int;
            var zy:int;
            var cx:int = this.cx;
            var cy:int = this.cy;
            var xx:int;
            var yy:int;
            var iter:int;

            xx = yy = iter = 0;
            zx = cx;
            zy = cy;
            for(; int(xx+yy) < (4 << 13) && iter < 0x100; iter++) {
                xx = int(zx*zx) >> 13;
                yy = int(zy*zy) >> 13;
                zy = int(int(zx*zy) >> 12) + cy; // zy = 2*zx*zy + cy
                zx = int(xx-yy) + cx; // zx = zx*zx - zy*zy + cx
            }

            this.iter = iter;
        }
    }
}