Chinaunix首页 | 论坛 | 博客
  • 博客访问: 159751
  • 博文数量: 56
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 502
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-18 14:21
文章分类

全部博文(56)

文章存档

2010年(39)

2009年(17)

我的朋友

分类: C/C++

2010-07-11 11:50:33

说明:
代码中定义了一个全局的变量PerformanceDaemon Perf;因此使用不是很方便。尝试改成单例

改编自C++简单的函数计时方法(Windows版),使用比较方便。

#include "iostream"
using namespace std;
class CMyclass
{
public:
    static CMyclass * GetInstance()
    {
        static CMyclass myclass;
        return &myclass;
    }
    CMyclass():value(0)
    {
    }
    ~CMyclass()
    {}
    int value ;
    void print()
    {
        value++;
        cout<<"CMyclass:"<<value<<endl;
    }
};


函数计时只需要包含以下头文件:

//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


这是一个简单的使用例子:

#include "performance.h"

void test()
{
     _PF;
   int i = 0;
   int c;
   while(i < 1000000)
   {
     for(int j = 0;j < 300;j++)
     c =( i * i/5)/6;
     i++;
   }
}
int main()
{
    _PF;
  test();
  test();
  printf("test\n");
}

编译:
g++ -o PerformanceWatcher test.cpp -Wall -lrt -g

程 序正常退出时输出结果:
FunctionName            ActiveTime      Average   Called
            main     2.372887   2.372887     1
            test     2.372736   1.186368     2
阅读(871) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~