0

今天我尝试为 javascript 函数编写一个简单的 prophiler 实用程序。问题是我启动的交互越多,系统速度就越慢,所以我认为在某些时候我有内存泄漏导致这个问题。实验代码如下。

//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

最后我发现了错误。这是一个算法误解。显然,每次调用都会增加 25 毫秒的延迟,因为 _startMark = new Date().getTime(); 比较后调用!现在它工作得很好!

于 2013-05-27T17:38:23.563 回答
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 回答