项目中经常需要统计调用一个外部接口的耗时,在做性能测试时也常需要分析N次调用所需时间,这类统计有一个共性点,即关注调用或执行的相对时间,而不关心绝对时间。 因此,为了性能起见,无需每次都调用gettimeofday,而只需读取系统的时间戳计数器中时间即可。
代码路径如下:http://modulecall.googlecode.com/svn/trunk/tar/modulecall.tar
类代码如下所示:
/*
* author nellson
* date 2010-07-18
* note calc time cost when call another module
*/
#ifndef _MODULE_CALL_H_
#define _MODULE_CALL_H_
#include "tsc.h"
namespace modulecall
{
#define call_start() CModuleCall::Instance()->Start();
#define call_end() CModuleCall::Instance()->End();
#define call_timecost() CModuleCall::Instance()->TimeCost()
class CModuleCall
{
public:
static CModuleCall * Instance()
{
if (!m_instance)
{
m_instance = new CModuleCall;
return m_instance;
}
return m_instance;
};
public:
void Start()
{
mtime(m_msec);
};
void End()
{
long long endtime;
mtime(endtime);
m_msec = endtime - m_msec;
};
long long TimeCost()
{
return m_msec;
};
private:
CModuleCall(){tsc_init();};
virtual ~CModuleCall(){};
protected:
long long m_msec;
protected:
static CModuleCall * m_instance;
};
CModuleCall * CModuleCall::m_instance = 0;
};
#endif
使用方式也很简单,下面是一个demo
#include "module_call.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
void call_module()
{
static int times = 1;
int t = rand()%100;
usleep(t*1000);
printf("CallModule times=%d sleep=%d/n", times, t);
times++;
}
int main(int argc, char ** argv)
{
srand(time(NULL));
if (argc < 2)
{
printf("Usage:%s calltimes/n", argv[0]);
return -1;
}
int times = atoi(argv[1]);
for (int i = 0; i < times; i++)
{
modulecall::call_start();
call_module();
modulecall::call_end();
printf("TimeCost=%lld/n", modulecall::call_timecost());
}
return 0;
}
有一点要注意的是,这里timecost得到的时间是毫秒,如果要取微秒也是可以的,只需要修改下tsc.h和tsc.cpp即可。这里即毫秒的原因是对于外部接口调用而言,时间开销一般在毫秒级,所以精度不需要那么准确。