bitflag

by umhr
こういうBitFlagって処理速度的に意味あるの??の疑問のためのテスト
BitFlag一般の話ではなくて。
結論:意味ねーよ!
♥0 | Line 156 | Modified 2010-12-25 23:56:03 | MIT License
play

ActionScript3 source code

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

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;
    
    
    /**
     * ...
     * @author umhr
     */
    public class Main extends Sprite 
    {
        private var _dataList:Array;
        private var _textField:TextField;
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            _dataList = [];
            var n:int = 10000;
            for (var i:int = 0; i < n; i++) {
                var m:int = 3;
                for (var j:int = 0; j < m; j++) {
                    var p0:int = int(Math.random() * 10);
                    var p1:int = int(Math.random() * 10);
                    var p2:int = int(Math.random() * 10);
                    if(Math.random() > 0.9){
                        p2 = -1;
                        if (Math.random() > 0.9) {
                            p1 = -1;
                        }
                    }
                    //個別用BitFlagを用意
                    var bitFlag0:uint = 0;
                    if (p0 > -1) {
                        bitFlag0 = 1 << p0;
                    }
                    var bitFlag1:uint = 0;
                    if (p1 > -1) {
                        bitFlag1 = 1 << p1;
                    }
                    var bitFlag2:uint = 0;
                    if (p2 > -1) {
                        bitFlag2 = 1 << p2;
                    }
                    
                    //一括用BitFlagを用意
                    var bitFlagAll:uint = 0;
                    if (p0 > -1) {
                        bitFlagAll = 1 << p0+20;
                        if (p1 > -1) {
                            bitFlagAll += 1 << p1+10;
                            if (p2 > -1) {
                                bitFlagAll += 1 << p2;
                            }
                        }
                    }
                    _dataList.push( { "title":i + "_" + j, "p0":p0, "p1":p1, "p2":p2 , "b0":bitFlag0 , "b1":bitFlag1 , "b2":bitFlag2, "bitFlagAll":bitFlagAll } );
                }
            }
            
            //確認用テキストフィールド
            _textField = new TextField();
            _textField.width = stage.stageWidth;
            _textField.height = stage.stageHeight;
            this.addChild(_textField);
            
            _textField.appendText("1回目\n");
            serch();
            
            _textField.appendText("2回目\n");
            serch();
            
            _textField.appendText("3回目\n");
            serch();
        }
        private function serch():void {
            
            //検索キーを設定
            var keys:Array = [[3,3,3],[7,4,1],[1,2,1],[6,1,8],[3,2,2],[1,1,7],[0,2,5],[9,3,1],[4,4,4],[8,9,6]];
            //検索キーをビット化
            var bitFlagKeys:Array = [];
            var bitFlagAllKeys:Array = [];
            var n:int = keys.length;
            for (var i:int = 0; i < n; i++) {
                bitFlagKeys.push([1 << keys[i][0], 1 << keys[i][1], 1 << keys[i][2]]);
                bitFlagAllKeys.push((1 << keys[i][0] + 20) | (1 << keys[i][1] + 10) | (1 << keys[i][2]));
            }
            
            
            //計測用Number
            var time:Number;
            
            //そのまま比較
            var result:Array = [];
            time = new Date().time;
            for (i = 0; i < n; i++) {
                result = result.concat(objectMatch.apply(this, keys[i]));
            }
            _textField.appendText("そのまま比較:" + (new Date().time - time) + "ミリ秒 \n");
            
            
            //ビットフラグ化して比較
            var bitFlagResult:Array = [];
            time = new Date().time;
            for (i = 0; i < n; i++) {
                bitFlagResult = bitFlagResult.concat(bitFlagMatch.apply(this, bitFlagKeys[i]));
            }
            _textField.appendText("ビットフラグ化して比較:" + (new Date().time - time) + "ミリ秒 \n");
            
            
            //3つの値をビットフラグでくっつけて比較(一部処理を単純化)
            //-1の場合の処理を端折っている。
            var bitFlagAllResult:Array = [];
            time = new Date().time;
            for (i = 0; i < n; i++) {
                bitFlagAllResult = bitFlagAllResult.concat(bitFlagAllMatch(bitFlagAllKeys[i]));
            }
            _textField.appendText("3つの値をビットフラグでくっつけて比較(一部処理を単純化):" + (new Date().time - time) + "ミリ秒 \n");
            
            
            //対照として、関数を通すだけで比較などはしない
            time = new Date().time;
            for (i = 0; i < n; i++) {
                (nullFunction(bitFlagAllKeys[i]));
            }
            _textField.appendText("対照として、関数を通すだけで比較などはしない:" + (new Date().time - time) + "ミリ秒 \n");
            
            _textField.appendText(_dataList.length + "個のデータを" + keys.length + "個のキーで比較\n");
            
            _textField.appendText("\n");
            
            
            trace(result.length, bitFlagResult.length, bitFlagAllResult.length);
        }
        
        //そのまま比較
        private function objectMatch(k0:int, k1:int, k2:int):Array {
            var result:Array = [];
            var n:int = _dataList.length;
            for (var i:int = 0; i < n; i++) {
                if (_dataList[i].p0 == k0) {
                    if (_dataList[i].p1 == -1 || _dataList[i].p1 == k1) {
                        if (_dataList[i].p2 == -1 || _dataList[i].p2 == k2) {
                            result.push(_dataList[i]);
                        }
                    }
                }
            }
            return result;
        }
        
        //ビットフラグ化して比較
        private function bitFlagMatch(k0:int, k1:int, k2:int):Array {
            var result:Array = [];
            var n:int = _dataList.length;
            for (var i:int = 0; i < n; i++) {
                if (_dataList[i].b0 & k0) {
                    if (_dataList[i].p1 == -1 || _dataList[i].b1 & k1) {
                        if (_dataList[i].p2 == -1 || _dataList[i].b2 & k2) {
                            result.push(_dataList[i]);
                        }
                    }
                }
            }
            return result;
        }
        
        //3つの値をビットフラグでくっつけて比較(一部処理を単純化)
        private function bitFlagAllMatch(key:uint):Array {
            var result:Array = [];
            var n:int = _dataList.length;
            for (var i:int = 0; i < n; i++) {
                if (_dataList[i].bitFlagAll == key) {
                    result.push(_dataList[i]);
                }
            }
            return result;
        }
        
        //対照として、関数を通すだけで比較などはしない
        private function nullFunction(key:uint):Array {
            var result:Array = [];
            var n:int = _dataList.length;
            for (var i:int = 0; i < n; i++) {
                if (true) {
                    if (true) {
                        result.push(i);
                    }
                }
            }
            return result;
        }
        
        
    }
    
}