0

今日は、javascript 関数用の単純なプロファイラ ユーティリティを作成しようとしました。問題は、起動する対話が増えるほどシステムの速度が低下することです。そのため、ある時点でこの問題につながるメモリ リークが発生していると思います。実験のコードは次のとおりです。

//Benchmark prototype
var Prophiler = (function( ){

    var _benchMark = (function( func, duration, callBack ){
        var _interval = 1000;
        var _startMark = new Date().getTime();
        var _now = _startMark;
        var _count = 0;
        var _rounds = 0;
        var _throttle = (function( ){
            while( ( _now - _startMark ) < _interval ){
                func( );
                _now = new Date().getTime( );
                _count++;   
            } 
            _startMark = new Date().getTime();
            _rounds++;
            if( _rounds <= ( duration ) ){
                window.setTimeout( _throttle, 25 );
                return false;
            }
            else{
                var _res = {};
                _res.elapsedTime = duration;
                _res.executions = _count;
                _res.averageTime = _res.elapsedTime / _res.executions;
                _res.averageTimeMs = _res.averageTime * 1000; 
                callBack( _res );
                return false;
            }
        });
        _throttle( );                                   
    });

    return{
        getProphile : function( params ){
            _benchMark( params.subject, params.duration, params.callBack );
        }
    }

})( );

//Test
var sumNum = function( param1, param2 ){
    var y = param1;
    for( var i = 0; i < param2; i++ ){
        y += param2;
    }           
};

Prophiler.getProphile({
    subject: function( ){
        sumNum( 10, 30 );
    },
    duration: 5,
    callBack: function( data ){
        console.log( data );
    }       
});
4

2 に答える 2

0

モジュール パターンとプロトタイプ パターンを比較するためだけに。パフォーマンスの向上は Chrome でより顕著ですが、Firefox でも確認できます。

        function BenchMark(fn, duration, callback){
            this.fn = fn;
            this.duration = duration;
            this.callback = callback;
            this.rounds = 0;
            this.count = 0
            this.timerId = null;
            this.startMark = (new Date()).getTime();
            this._execute = this.scope(this, 'execute');
            this._execute();
        }

        BenchMark.prototype.scope = function(context, method){
            return function(){
                context[method].call(context);
            }
        }

        BenchMark.prototype.execute = function(){ 
            if(this.timerId !== null){
                clearTimeout(this.timerId);
            }
            var count = 0, now = this.startMark;
            while( (now - this.startMark) <  1000){
                this.fn();
                now = (new Date()).getTime();
                count++;
            }
            this.startMark = (new Date()).getTime();
            this.count += count;
            this.rounds++;

            if(this.rounds <= this.duration){
                this.timerId = setTimeout(this._execute, 25);
                return false;
            }else{
                var averageTime = this.duration / this.count;
                this.callback({
                    elapsedTime : this.duration,
                    executions : this.count,
                    averageTime : averageTime,
                    averageTimeMs : averageTime * 1000
                });
                return false;
            }
        }

        function Profiler(){

        }

        Profiler.prototype.benchmark = function(fn, duration, callback){ 

            new BenchMark(fn, duration, callback);
        }

        function sumNum( param1, param2 ){
            var y = param1;
            for( var i = 0; i < param2; i++ ){
                y += param2;
            }           
        };

        var profiler = new Profiler();

        var profilerCalled = 0;
        var intervalId = setInterval(function(){ 
            console.log('Profiler: ', profilerCalled+1)
            profiler.benchmark(function(){ 
                sumNum(10, 30)
            }, 5, function(result){ 
                console.log(result)
            });
            profilerCalled++;
            if(profilerCalled == 10){
                clearInterval(intervalId);
                console.log('stopped')
            }
        }, 10000);
于 2013-05-26T22:28:56.690 に答える