您的位置:首页 > 编程语言 > C语言/C++

提高C++程序效率

2009-06-13 13:38 375 查看
查看原文

这几天一直抽时间研究C/C++程序的效率问题,收获不小。
在开发效率方面,C的重点在于算法和数据结构,C++则要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域。对于很简单的问题,当然C的代码要比C++ 来的短, 但对于比较复杂的问题,OOP的优点就体现出来了。C++面向对象方法开发出来的代码容易理解,容易维护。当问题复杂以后,C++的代码肯定比C的代码来的短。
在运行效率方面,由于C++的精心设计,C++程序其实并不比C程序低多少。导致C++效率低的一个重要原因是临时对象的滥用,因为对象在创建和释放时需要调用构造函数和析构函数,在一个大的类里这个开销很可观,因而需要灵活使用各种机制,减少临时对象的产生,从而提高程序效率。以下以一个Leader类来说明:
1. 类的构造函数、赋值函数(使用引用,减少临时对象的产生)

class Leader
{
string name;
int no;
double salary;
public:
Leader(){}
Leader(int o,string n):no(o),name(n){} //赋值列表可避免调用成员属性的默认构造函数
Leader(const Leader& l):no(l.no),name(l.name),salary(l.salary){}//拷贝构造函数,使用引用传参
Leader& operator=(const Leader& l)//赋值操作符重载
{
this->name = l.name;
this->no = l.no;
this->salary = l.salary;
return *this;
}
};
如果这么复制一个对象:
Leader l;//调用默认构造函数
l = m;//m也是一个Leader对象,调用赋值操作符函数
那不如这么写,这样更高效:
Leader l(m); //只调用一次拷贝构造函数
当然,不只是类的成员函数,非成员函数也可使用引用传参来减少临时对象的构造。
效率不高的做法     高效率做法
void print(Leader l) void print(const Leader& l)
{ {
//函数体 //函数体
} }

2. 只要有可能就推迟变量定义。在C中要将所有的局部变量定义在函数体头部,考虑到C++中对象创建的开销,这不是一个好习惯。如下例,如果大部分情况下b为"真",则拖延ld的定义可以大大提高函数的效率。
效率不高的做法 高效率做法
void Function( bool b ) void Function( bool b )
{ {
Leader ld; if(b)
if( b) {
{ // do something without xx
// do something without xx return;
return; }
} Leader ld;
//对ld进行操作 //对ld进行操作
} }

3. 那么对于循环会如何呢?如果一个变量仅仅在一个循环内使用,是循环外面定义它并在每次循环迭代时赋值给它更好一些,还是在循环内部定义这个变量更好一些呢?也就是说,下面这两个大致的结构中哪个更好一些?
// Approach A: define outside loop // Approach B: define inside loop
Leader l;
for (int i = 0; i < n; ++i) for (int i = 0; i < n; ++i)
{ {
l = some value dependent on i; Leader l(some value dependent on i);
... ...
} }

下面是这两个方法的成本:
方法 A:1 个构造函数 + 1 个析构函数 + n 个赋值。
方法 B:n 个构造函数 + n 个析构函数。
对于那些赋值的成本低于一个构造函数/析构函数对的成本的类,方法 A 通常更高效。特别是在n变得很大的情况下。否则,方法 B 可能更好一些。此外,方法 A 与方法 B 相比,使得名字 l 在一个较大的区域(包含循环的那个区域)内均可见,这可能会破坏程序的易理解性和可维护性。因此得出以下结论:除非确信以下两点:
(1)赋值比构造函数/析构函数对成本更低
(2)你正在涉及你的代码中的性能敏感的部分
否则,应该默认使用方法 B。
但是我始终没查到简单类型,如int,char,string等的构造与赋值成本的比较,而这些是复杂类构造与赋值成本的基本组成。那么对于这些简单类型,A和B哪种方法更高效呢?请高手指点!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: