c++性能优化笔记-跟踪实现下的性能隐患

跟踪实现下的性能隐患
我们在调试代码的时候,会有很多不同的手段。像我的话最常使用的是打日志Log,通过Log可以很清晰的判断出代码的逻辑,
再进一步的深入查找问题出现的根源。其实还有很多其他的方法,比如墓碑文件,看Trace等等。实现记录日志以及记录代码执行相关的Trace是我们整个项目组成不可或缺的一部分,有的时候往往Log打得好,问题查得更快,整个项目也会更加的健壮。
但是,我们在项目中往往会忽视这些Trace代码带来的性能消耗。由于工作中的项目,几十万甚至几百万的代码量,程序员的Log为了形成统一的风格以及调查问题的便利,通常会有一个专门的Trace类来记录Trace。构造函数和析构函数都会记录日志,同时也会有相应的函数调用。比如举个例子:

class Trace {
public:
    Trace(const string& name);
    ~Trace();
    void debug(const string& msg);
    static bool traceIsActive;
private:
    string theFunctionName;
};

Trace::Trace(const string& name)
    : theFunctionName(name)
{
    if (traceIsActive) {
    	cout << "EnterFunction: " << name << endl;
    }
}

void Trace::debug(const string& msg)
{
	if (traceIsActive) {
		cout << msg << endl;
	}
}

Trace::~Trace()
{
	if (traceIsActive) {
		cout << "Exit Function: " << theFunctionName << endl;
	}
}

上面的例子,如果当前trace为active的状态(这也就引出我们一个打印Trace的习惯,我们需要调试的时候可以将开关打开,平时正常运行的时候需要关掉Trace,以免影响性能;同时ifdef的方式开关Trace也是一种常见的方式,但是缺点就是需要二次编译),构造Trace、析构Trace以及正常的调用debug都会打印Log。在书中了解到随机将此类应用到项目中,在关键的位置加上Trace,得到的结果为性能变为原来的五分之一,这是一个什么样的概念?那到底问题出在哪边呢?且听我继续分析。
我们都知道的是对于开销比较大的几个操作:1. IO操作;2. 函数调用;3. 对象复制。因此在多数的情况下,我们在coding的时候会比较注重这三个方面的开销,尽量少的使用以上三种方式。但是在我们上面的debug的例子中,还有一个开销是我们不可忽视的,上面的Trace类定义时,操作系统会自动分配内存给变量,但往往我们如果不需要debug的时候,这些变量的定义仍然占用着空间,这无疑是一种浪费。
我们针对这种浪费进行改进才会对我们代码进行针对性的优化。首先我们想到的是Trace类中string对象未使用指针,这样的话赋值时会造成空间的浪费,因此我们在构造Trace的时候可以传入char*类型的指针,以及内部的string对象改用指针,这样的话就可以减少对象的赋值带来的空间占用。同时我们考虑到Trace类本身体量较大,因此不适合较小的函数使用。
修改后如下:

class Trace {
public:
    Trace(const char* name);
    ~Trace();
    void debug(const string& msg);
    static bool traceIsActive;
private:
    string* theFunctionName;
};

Trace::Trace(const char* name)
{
    if (traceIsActive) {
	theFunctionName = new string(name);
    }
}

void Trace::debug(const string& msg)
{
	if (traceIsActive) {
		cout << msg << endl;
	}
}

Trace::~Trace()
{
	if (traceIsActive) {
		if (NULL != theFunctionName) {
			delete theFunctionName;
			theFunctionName = NULL;
		}
	}
}

本章主要的内容其实就是要告诉我们需要在编程的时候注意一些隐形的开销,往往被我们忽视的就是最终造成问题的原因。比如上面的类的构造和析构的开销就是如此。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值