游戏服务器之性能统计

发表于2018-04-22
评论0 1.4k浏览
性能统计分析器用来统计多个函数在一定执行次数下的执行时间,并输出函数执行时间较长的函数名和时间。

(1)性能统计分析器
class Performance_Statistics  
{  
    private:  
        struct Performance  
        {  
            Performance():_times(0),_total_time(0) {}  
            /**  
             * \author: cjy  
             * \description: 执行的次数  
             */  
            unsigned long _times;  
            /**  
             * \author: cjy  
             * \description:执行的总时间  
             */  
            unsigned long _total_time;  
        };  
        std::map<std::string, Performance> _times;  
        timer _log_timer;  
    public:  
        Performance_Statistics(const int how_long) : _log_timer(how_long) {}  
        ~Performance_Statistics() {}  
        void inc(const std::string &func, const unsigned long total)  
        {  
            Performance &mt = _times[func];  
            if (mt._times)  
            {  
                ++mt._times;  
                mt._total_time += total;  
            }  
            else  
            {  
                ++mt._times;  
                mt._total_time = total;  
            }  
        }  
        void reset(const realtime &ct, const bool force_print)  
        {  
            if (force_print || _log_timer(ct))  
            {  
                g_log->debug("[分时统计]:%s, %lu", force_print ? "force" : "timer", _times.size());  
                for(std::map<std::string, Performance>::iterator it = _times.begin(); it != _times.end(); ++it)  
                {  
                    if (it->second._times && (it->second._total_time / 1000000L) > 5)//输出5ms以上的  
                    {  
                        g_log->debug("[分时统计]:%s, %lu毫秒, %lu次, %lu毫秒/次",it->first.c_str(), it->second._total_time /1000000L, it->second._times, (it->second._total_time / 1000000L) / it->second._times);  
                    }  
                }  
            }  
            _times.clear();  
        }  
};  

(2)统计方便函数,在构造函数和析构函数里执行时间统计
class Function_Exe_Time  
{  
private:  
    const std::string _func;  
    struct timespec _tv_1;  
public:  
    static Performance_Statistics my_func;  
    Function_Exe_Time(const std::string &func) : _func(func)  
    {     
        clock_gettime(CLOCK_REALTIME, &_tv_1);  
    }     
    ~Function_Exe_Time()  
    {     
        struct timespec _tv_2;  
        clock_gettime(CLOCK_REALTIME, &_tv_2);  
        unsigned long end=(unsigned long)_tv_2.tv_sec*1000000000L + _tv_2.tv_nsec;  
        unsigned long begin=(unsigned long)_tv_1.tv_sec*1000000000L + _tv_1.tv_nsec;  
        my_func.inc(_func, end-begin);  
    }     
};  

(3)定时器
/** 
 * \author cjy 
 * \description 定时器 
 * 固定时间间隔的定时器,方便对于时间间隔的判断,精确到毫秒级 
 */  
class timer  
{  
public:  
    /** 
    * \author cjy 
    * \description构造函数 
    * \param how_long 定时器的时间,单位:毫秒 
    * \param first 有些定时器可能希望在启动时就可以执行一次,所以不能直接addDelay哦 
    */  
    explicit timer(const int64 how_long, bool first=false, const int64 delay=0) : _long(how_long), _timer()  
    {  
        if(!first)  
        _timer.addDelay(_long+delay);  
    }  
    /** 
    * \author cjy 
    * \description构造函数 
    * \param how_long 定时器的时间,单位:毫秒 
    * \param first 有些定时器可能希望在启动时就可以执行一次,所以不能直接addDelay哦 
    * \param ctv 当前时间 
    */  
    explicit timer(const int64 how_long, bool first , realtime &ctv) : _long(how_long), _timer(ctv)  
    {  
        if(!first)  
        _timer.addDelay(_long);  
    }  
    /** 
    * \author cjy 
    * \description重新设置定时器的精度和开始计时时间 
    * \param how_long 定时器的时间,单位:毫秒 
    * \param ctv 当前时间 
    */  
    void reset(const uint64 how_long, const realtime &cur)  
    {  
        _long = how_long;  
        _timer = cur;  
        _timer.addDelay(_long);  
    }  
    /** 
    * \author cjy 
    * \description重新设置定时器的时间 
    * \param cur 指定定时器启动的时间 
    */  
    void current(const realtime &cur)  
    {  
        _timer = cur;  
    }   
    /** 
    * \author cjy 
    * \description延时定时器时间 
    * \param cur 指定定时器启动的时间 
    * \param delay 延时时间 
    */  
    void next(const realtime &cur, const uint32 delay)  
    {  
        _timer = cur;  
        _timer.addDelay(delay);  
    }   
    /** 
    * \author cjy 
    * \description重新设置定时器的时间 
    * \param cur 指定定时器启动的时间 
    */  
    void next(const realtime &cur)  
    {  
        _timer = cur;  
        _timer.addDelay(_long);  
    }   
    /** 
    * \author cjy 
    * \description倒计时剩余秒数.不受时间调整影响. 
    * \param cur 当前时间  
    * return 剩余描述 
    */  
    inline uint32 leftSec(const realtime &cur)  
    {  
        return (_timer.sec() > cur.sec()) ? (_timer.sec() - cur.sec()) : 0;  
    }   
    /** 
    * \author cjy 
    * \description倒计时剩余毫秒数.受时间调整影响 
    * \param cur 当前时间  
    * return 剩余值 
    */  
    inline uint64 leftMSec(const realtime &cur)  
    {  
        return (_timer._msec > cur._msec) ? (_timer._msec - cur._msec) : 0;   
    }   
    /** 
    * \author cjy 
    * \description定时器检查 
    * \param cur 检查定时器的时间 
    * return 是否到达指定时间 
    */  
    inline bool operator() (const realtime &cur)  
    {  
        if (_timer._msec > cur._msec)  
        {  
            return false;  
        }  
        addDelay(cur);  
        return true;  
    }  
    inline void addDelay(uint64 addLong)//添加延迟  
    {  
        _timer.addDelay(addLong);  
    }  
private:  
    /** 
    * \author cjy 
    * \description定时器时间间隔 
    */  
    uint64 _long;  
    /** 
    * \author cjy 
    * \description上次检查定时器的时间 
    */  
    realtime _timer;  
private:  
    /** 
    * \author cjy 
    * \description非严格检测,存在积累误差 
    * 从效率方面考虑,严格监测定时器的需求并不是必须的,去除对严格监测的支持 
    */  
    inline void addDelay(const realtime& cur)  
    {  
        _timer = cur;  
        _timer.addDelay(_long);  
    }  
};  

(4)测试实例
测试ai攻击处理花费时间
{  
    Function_Exe_Time func("NPC_AI_ATTACK"STR(__LINE__));  
    return doAttackAI();  
} 
来自:https://blog.csdn.net/chenjiayi_yun/article/details/35276861

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引