性能统计分析器用来统计多个函数在一定执行次数下的执行时间,并输出函数执行时间较长的函数名和时间。
目录:
(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();
}