withステートメントの性能測定

by ashitaka forked from Template for Performance Check (diff: 125)
with文の性能測定
@author kawakita
@version 0.1
♥0 | Line 270 | Modified 2010-03-31 03:58:51 | MIT License
play

ActionScript3 source code

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

// forked from kawakita's Template for Performance Check
package  {
    
    import flash.display.MovieClip;
    import flash.system.System;
    import flash.events.Event;
    
    /**
    * with文の性能測定
    * @author kawakita
    * @version 0.1
    */
    public class TestTemplate extends MovieClip{
        
        //------- CONST ------------------------------------------------------------------------
        // この回数処理させた前後の時間を元に計測します
        // ここまで増やさないと違いが出ません(汗)
        private static const _TIMES:uint = 10000000;
 
         //------- MEMBER -----------------------------------------------------------------------
        private var _output:Output;
        
        //------- PUBLIC -----------------------------------------------------------------------
        /** コンストラクタ. */
        public function TestTemplate() {
            // init output;
            _output = new Output();
            _output.setSize( stage.stageWidth, stage.stageHeight );
            stage.addEventListener(Event.RESIZE, function(e:Event):void {
                _output.setSize( stage.stageWidth, stage.stageHeight );
            });
            addChild(_output);

            // 測定用のオブジェクト            
            var sample:Sample = new Sample(10, 20, 30);
            sample.child = new Sample(10, 20, 30);
            sample.child.child = new Sample(10, 20, 30);
            
            _output.print("with文 性能測定");
            _output.print("\nプロパティ(data1~3)へのアクセスを" + _TIMES + "回繰り返した際の秒数を測定");

            _output.split(20);
            _output.print("■自クラスのプロパティへアクセスした場合")
            _output.print("sample.data1~3")
            test(function():void{
                for (var i:uint = 0; i < _TIMES; i++){
                    sample.data1 = 100;
                    sample.data2 = 200;
                    sample.data3 = 300;
                }
            });
            _output.print("\nwith(sample){ data1~3 }")
             test(function():void{
                for (var i:uint = 0; i < _TIMES; i++){
                    with(sample){
                        data1 = 100;
                        data2 = 200;
                        data3 = 300;
                    }
                }
            });
            
            _output.split(20);
            _output.print("■子クラスのプロパティへアクセスした場合")
            _output.print("sample.child.data1~3")
            test(function():void{
                for (var i:uint = 0; i < _TIMES; i++){
                    sample.child.data1 = 100;
                    sample.child.data2 = 200;
                    sample.child.data3 = 300;
                }
            });
            _output.print("\nwith(sample.child){ data1~3 }")
             test(function():void{
                for (var i:uint = 0; i < _TIMES; i++){
                    with(sample.child){
                        data1 = 100;
                        data2 = 200;
                        data3 = 300;
                    }
                }
            });
            
            _output.split(20);
            _output.print("■孫クラスのプロパティへアクセスした場合")
            _output.print("sample.child.child.data1~3")
            test(function():void{
                for (var i:uint = 0; i < _TIMES; i++){
                    sample.child.child.data1 = 100;
                    sample.child.child.data2 = 200;
                    sample.child.child.data3 = 300;
                }
            });
            _output.print("\nwith(sample.child.child){ data1~3 }")
             test(function():void{
                for (var i:uint = 0; i < _TIMES; i++){
                    with(sample.child.child){
                        data1 = 100;
                        data2 = 200;
                        data3 = 300;
                    }
                }
            });

            _output.split(20);
            _output.print("■子&孫クラスのプロパティへアクセスした場合")
            _output.print("sample.child.data1~3 , sample.child.child.data1~3")
            test(function():void{
                for (var i:uint = 0; i < _TIMES; i++){
                    sample.child.data1 = 100;
                    sample.child.data2 = 200;
                    sample.child.data3 = 300;
                    sample.child.child.data1 = 100;
                    sample.child.child.data2 = 200;
                    sample.child.child.data3 = 300;
                }
            });
            _output.print("\nwith(sample.child){ data1~3 , child.data1~3 }")
             test(function():void{
                for (var i:uint = 0; i < _TIMES; i++){
                    with(sample.child){
                        data1 = 100;
                        data2 = 200;
                        data3 = 300;
                        child.data1 = 100;
                        child.data2 = 200;
                        child.data3 = 300;
                    }
                }
            });
        }
        
        /**
         * 引数で与えられた関数を実行し、メモリ使用量と所要時間を調べます.
         * @param	testFunction
         */
        public function test( testFunction:Function ):void {
            var b4Mem:Number = System.totalMemory;
            var now:Number = new Date().getTime();
            testFunction();
            _output.print({
                "  Time" : ( new Date().getTime() - now ) + " ms"
            });
        }
        
        //------- PRIVATE ----------------------------------------------------------------------
        //------- PROTECTED --------------------------------------------------------------------
        //------- INTERNAL ---------------------------------------------------------------------
    
    }
    
}

import flash.display.*;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.text.*;
import flash.ui.Keyboard;

class Output extends MovieClip{
    
    //------- MEMBER ----------------------------------------------------------------------
    private var _width:Number;
    private var _height:Number;
    private var _totalHeight:Number;
    private var _scrollY:Number;
    private var _currentItem:DisplayObject;
    private var _itemList:Array;
    
    //------- PUBLIC ----------------------------------------------------------------------
    
    /** コンストラクタ. */
    public function Output():void {
        _scrollY = 0;
        _totalHeight = 0;
        _currentItem = null;
        _itemList = [];
        addEventListener(Event.ADDED_TO_STAGE, _onAddedToStage );
    }
    
    /** 描画の横幅. */
    override public function get width():Number { return super.width; }
    override public function set width(value:Number):void {
        if ( value == width ) return;
        setSize( value, height );
    }
    
    /** 描画の縦幅. */
    override public function get height():Number { return _totalHeight; }
    override public function set height(value:Number):void {
        if ( value == height ) return;
        setSize( width, value );
    }
    
    /**
     * 描画サイズを指定します.
     * @param	w
     * @param	h
     */
    public function setSize( w:Number, h:Number ):void {
        _width = w;
        _height = h;
        _updateAll();
    }
    
    /**
     * 引数で渡した内容を出力します.
     * @param	value
     */
    public function print( value:* ):void {
        if( !_currentItem || !(_currentItem is TextField ) ){
            _currentItem = _createTextField();
            _itemList[_itemList.length] = addChild(_currentItem);
        }
        var tf:TextField = _currentItem as TextField;
        tf.appendText( ( ( value is String ) ? value : _printObject( value ) ) + "\n" );
        _updateY();
    }
    
    /**
     * 分割のための処理を提供します.
     */
    public function split( size:Number = 10, useLine:Boolean = true ):void {
        _currentItem = new Split( size, useLine );
        _currentItem.width = _width;
        _itemList[_itemList.length] = addChild( _currentItem );
        _updateY();
    }
    
    //------- PRIVATE ----------------------------------------------------------------------
    /** 描画をすべて更新. */
    private function _updateAll():void {
        var len:uint = _itemList.length;
        for (var i:uint = 0; i < len; i++){
            _itemList[i].width = _width;
        }
    }
    
    /** 高さのみ更新. */
    private function _updateY():void {
        var d:DisplayObject;
        var bottom:Number = 0;
        var len:uint = _itemList.length;
        for (var i:uint = 0; i < len; i++) {
            d = _itemList[i];
            d.y = bottom;
            bottom += d.height;
        }
        _totalHeight = bottom + 50;
    }
    
    /** オブジェクトを出力.*/
    private function _printObject( obj:Object, tabLength:uint = 0 ):String {
        // Create Tab.
        var t:String = "";
        while ( t.length < tabLength ) t += " ";
        // Create Text.
        var strArr:Array = [];
        for ( var key:String in obj ) {
            if ( obj[key] is String || obj[key] is Number ) {
                strArr[strArr.length] = t + key + " : " + obj[key];
            }else if ( obj[key] is Function ) {
                strArr[strArr.length] = t + key + " : " + obj[key].toString();
            }else {
                var sChar:String, eChar:String;
                if ( obj[key] is Array ) {
                    sChar = "["; eChar = "]";
                }else {
                    sChar = "{"; eChar = "}";
                }
                strArr[strArr.length] = [
                    t + key + " : " + sChar,
                    _printObject( obj[key], tabLength + 2 ),
                    t + eChar
                ].join("\n");
            }
        }
        // Return Created Text.
        return strArr.join("\n");
    }
    
    /** TextField の 生成 */
    private function _createTextField( format:TextFormat = null ):TextField {
        var tf:TextField = new TextField();
        tf.autoSize = TextFieldAutoSize.LEFT;
        tf.defaultTextFormat = format || new TextFormat("_等幅");
        tf.multiline = true;
        tf.text = "";
        tf.wordWrap = true;
        tf.width = _width;
        return tf;
    }
    
    private function _onAddedToStage(e:Event):void {
        stage.addEventListener(KeyboardEvent.KEY_DOWN, _onKeyDown );
    }
    
    private function _onKeyDown(e:KeyboardEvent):void {
        if ( e.keyCode == Keyboard.DOWN ) {
            _scrollY += 20;
        }else {
            _scrollY -= 20;
        }
        _scrollY = Math.max( 0, Math.min( _totalHeight - _height, _scrollY ) );
        scrollRect = new Rectangle( 0, _scrollY, _width, _height );
    }
    
}

class Split extends MovieClip {
    
    private static var _BMD:BitmapData;
    private var _size:Number;
    private var _useLine:Boolean;
    
    /** コンストラクタ. */
    public function Split( size:Number, useLine:Boolean ):void {
        if ( !_BMD ) {
            _BMD = new BitmapData( 2, 1 );
            _BMD.setPixel32( 0, 0, 0xff000000 );
        }
        _size = size;
        _useLine = useLine;
    }
    
    override public function get width():Number { return super.width; }
    override public function set width(value:Number):void {
        graphics.clear();
        graphics.beginFill( 0xffffff, 0 );
        graphics.drawRect( 0, 0, value, _size );
        graphics.endFill();
        if ( _useLine ) {
            graphics.beginBitmapFill( _BMD );
            graphics.drawRect( 0, Math.round( _size / 2 ), value, 1 );
            graphics.endFill();
        }
    }
}

/**
 * withテスト用クラス
 * どこまでも深い子供を作れます
 */
class Sample
{
    public var child:Sample; // 入れ子構造にします
    public var data1:Number;
    public var data2:Number;
    public var data3:Number;

    public function Sample(data1:Number, data2:Number, data3:Number)
    {
        this.data1 = data1;
        this.data2 = data2;
        this.data3 = data3;
    }
}