游戏服务器之性能统计

性能统计分析器用来统计多个函数在一定执行次数下的执行时间,并输出函数执行时间较长的函数名和时间。


目录:

(1)性能统计分析器

(2)统计方便函数类,在构造函数和析构函数里执行时间统计

(3)定时器

(4)测试实例

内容:

(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();
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值