//performance.h
#ifndef PERFORMANCE_DAEMON
#define PERFORMANCE_DAEMON
#define PERFDATA_INIT_SIZE 32
#define PERFDATA_INC_SIZE 32
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <time.h>
class PerformanceDaemon
{
private:
typedef struct _PERF_DATA
{
int nID;
char* pstrName;
int TotolCalled;
double TotolTime;
//long long FuncBeginTime;
}PERF_DATA,*LPPERF_DATA;
LPPERF_DATA m_pDatas;
int m_dwUsed;
int m_dwSize;
//long long m_TickNow;
//long long m_Freq;
struct timespec m_TickNow;
//struct timespec m_Freq;
void SetSize(int dwSize)
{
assert(dwSize>m_dwUsed);
LPPERF_DATA pData=new PERF_DATA[dwSize];
memcpy(pData,m_pDatas,m_dwUsed*sizeof(PERF_DATA));
memset(pData+m_dwUsed,0,(dwSize-m_dwUsed)*sizeof(PERF_DATA));
delete []m_pDatas;
m_pDatas=pData;
m_dwSize=dwSize;
}
public:
static PerformanceDaemon * GetInstance()
{
static PerformanceDaemon Perf;
return &Perf;
}
PerformanceDaemon ()
{
m_pDatas=0;
m_dwUsed=0;
m_dwSize=0;
SetSize(PERFDATA_INIT_SIZE)
}
void FuncStart(const char* pstrName,int &nID)
{
if(nID>=m_dwUsed && nID!=0xFFFF) return;
if(nID==0xFFFF) //add new function record;
{
PERF_DATA data;
size_t nLenght;
nLenght=strlen(pstrName);
memset(&data,0,sizeof(data));
data.pstrName=new char[nLenght+1];
strcpy(data.pstrName,pstrName);
if(m_dwUsed >= m_dwSize)
SetSize(m_dwSize+PERFDATA_INC_SIZE);
nID=m_dwUsed++;
m_pDatas[nID]=data;
}
//QueryPerformanceCounter(&m_TickNow);
clock_gettime(CLOCK_MONOTONIC, &m_TickNow);
// printf("start : %lu\n", m_TickNow.tv_sec);
}
void GetTime(timespec *pTime)
{
*pTime=m_TickNow;
}
void FuncEnd(int nID,timespec *pTime)
{
timespec TickNow;
//QueryPerformanceCounter(&TickNow);
clock_gettime(CLOCK_MONOTONIC, &TickNow);
//printf("start : %lu\n", TickNow.tv_sec);
if(nID>=m_dwUsed && nID!=0xFFFF) return;
//m_pDatas[nID].TotolTime += TickNow.QuadPart-*pTime;
m_pDatas[nID].TotolTime += TickNow.tv_sec-(*pTime).tv_sec + (TickNow.tv_nsec - (*pTime).tv_nsec)/(double)(1000*1000*1000);
m_pDatas[nID].TotolCalled++;
m_TickNow = TickNow;
}
void DumpFunctionPerfmance()
{
char strBuffer[256];
printf("FunctionName\t\tActiveTime\tAverage\t Called\n");
for(int i=0;i<m_dwUsed;i++)
{
double t;
int n=m_pDatas[i].TotolCalled;
t=m_pDatas[i].TotolTime;///double(m_Freq);
sprintf(strBuffer,"%16s %12f\t%8f%6u\t\n",m_pDatas[i].pstrName,t,t/n,n);
printf(strBuffer);
}
}
~PerformanceDaemon ()
{
DumpFunctionPerfmance();
for(int i=0;i<m_dwUsed;i++)
{
delete []m_pDatas[i].pstrName;
}
delete []m_pDatas;
}
};
//PerformanceDaemon Perf;
class PerformanceWatcher
{
int dwID;
timespec StartTime; //为了解决嵌套调用问题
public:
//just for convinience
PerformanceWatcher(const char* pstrFunName,int &nID)
{
PerformanceDaemon::GetInstance()->FuncStart(pstrFunName,nID);
dwID=nID;
PerformanceDaemon::GetInstance()->GetTime(&StartTime);
}
~PerformanceWatcher()
{
PerformanceDaemon::GetInstance()->FuncEnd(dwID,&StartTime);
}
};
//#ifdef DEBUG
#define _PF \
static int __PerfCounter=0xFFFF;\
PerformanceWatcher __PerfWatcher(__FUNCTION__,__PerfCounter)
//#else
//#define _PF
//#endif
//#ifdef PERFORMANCE_USE
#endif
|