巧妙的利用C++的特性实现Profiling

软件中Profile的解释很多,有时候指的是一组设置值,这里说的Profile是对运行程序的数据采样,获得内存使用和运行时间的纪录,通过分析得以优化代码。

1)内存Profile。C++提供宏和函数重载的功能,由此可以添加对内存的纪录,将一下代码放在头文件中,项目中每个.cpp文件都include这个头文件,使其产生效应。

#ifdef _DEBUG
#define new((x)) newObj((__FUNCTION__, __LINE__, (x));
#define delete((x)) deleteObj(__FUNCTION__, __LINE__, (x));
inline void * newObj(const char * function, int line, size_t size)
{
    void ptr = (void *)malloc(size);
    //Record the function, line and size, ptr
    return ptr;
}
inline void deleteObj(const char * function, int line, void *ptr)
{
   //Record the function, line, and ptr.
   free ptr;
}
#endif

至于如何纪录添加释放内存,方法很多,可以直接打印出来或者写到一个文件,不过这样非常影响效率,而且不利于产生容易阅读的输出。比较合理的方法,建立一个Singletion的类,每次纪录都通过这个类添加纪录,这个类的析构函数把所有的纪录按照需要的方式dump出来。

重载new/delete仅仅用于做profile,在debug版本中发现内存分配问题,在release版本中通过不定义_DEBUG去掉。

1)运行时间Profile。要获得某一段代码的运行时间,就得在入口纪录一个时间,在出口记录一个时间,然后取二者之差,这样的代码比较难看,其实可以利用C++程序对局部变量的处理。C++程序执行到一个scope结束的时候会删除这个scope里面局部变量,也就是调用其的析构函数

#ifdef _DEBUG

#define PROFILE_BEGIN Profile p(__FILE__, __FUNCTION__, __LINE__);

class Profile

{

public:

    Profile(const char * file, const char *function, int line)

    {

         //record info

        beginTimestamp = ...//current time

    }

    ~Profile()

    {

         timeGap = current time - beginTimestamp;

         //register info

    }

private:

    int beginTimestamp;

    int timeGap;

};

#else

#define PROFILE_BEGIN

#endif

这样在源代码里面,只需要在一个函数入口写上PROFILE_BEGIN,就可以获得这个函数体的运行时间。

int foo()

{

     PROFILE_BEGIN

     //....

}

如果想要获得函数中某一部分code的运行时间,可以把这一部分用{}扩起来,在开始处加一个PROFILE_BEGIN.

如果想要获得函数中某一部分code的运行时间,可以把这一部分用{}扩起来,在开始处加一个PROFILE_BEGIN.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值