C++的一些优化操作
来源:互联网 发布:bitspirit mac 编辑:程序博客网 时间:2024/06/06 01:35
1.1.1 利用C++语言的优化机制
1.1.1.1 使用带赋值操作的变量声明
void assign(const C& c1)
{
C c2;
c2 = c1; // 有三个函数调用:一次默认构造函数、一次赋值函数和一次析构函数
}
void initialize(const C& c1)
{
C c2 = c1; // 只有一次拷贝构造函数和一次析构函数
}
1.1.1.2 使用时再声明对象
错误的用法
当is_C_Needed()返回false时,c1被白白构造了一次!
正确的用法
bool is_C_Needed();
void use()
{
C c1;
if (is_C_Needed() == false)
{
return; //c1 was not needed
}
//use c1 here
return;
}
void use()
{
if (is_C_Needed() == false)
{
return; //c1 was not needed
}
C c1; //moved from the block's beginning
//use c1 here
return;
}
1.1.1.3 使用成员初始化列表
使用成员初始化列表
class Person
{
private:
C c_1;
C c_2;
public:
Person(const C& c1, const C& c2 ): c_1(c1), c_2(c2) {}
};
在拷贝构造函数中初始化
Person::Person(const C& c1, const C& c2)
{
c_1 = c1;
c_2 = c2;
}
测试代码
int main()
{
C c; //created only once, used as dummy arguments in Person's constructor
for (int j = 0; j<30000000; j++)
{
Person p(c, c);
}
return 0;
}
测试结果
初始化方式
调用默认构造函数的次数
调用拷贝构造函数的次数
调用赋值函数的次数
调用析构函数的次数
使用成员初始化列表
0
60,000,000
0
60,000,000
拷贝函数中初始化
60,000,000
0
60,000,000
60,000,000
1.1.1.4 使用前向操作符(即使用前向++/--)
因为后向操作符会返回一个临时对象,所以使用前向操作符的效率更高:
class Date
{
private:
//...
int AddDays(int d);
public:
Date operator++(int unused);
Date& operator++();
};
Date Date::operator++(int unused) //postfix
{
Date temp(*this); //create a copy of the current object
this->AddDays(1); //increment current object
return temp; //return by value a copy of the object before it was incremented
}
Date& Date::operator++() //prefix
{
this->AddDays(1); //increment current object
return *this; //return by reference the current object
}
1.1.1.5 inline函数
inline函数具有函数展开的特征,同时又带有安全的类型信息(宏定义没有类型信息),它通过空间来换得时间,所以适当的使用inline函数可以提高代码的效率。
但是,一般只有简短的存取操作(比如get和set操作)、函数包装等会使用inline,同时能够得到效率的提高。如果一个代码量大的函数使用了inline,会导致执行程序的大小增大,甚至造成CPU的cache命中率降低。
此外,使用inline函数还需要注意,如果inline函数改变了(包括它使用的数据类型改变了),那么所有用到了这个头文件的函数必须重新编译。
1.1.1.6 避免临时对象
错误的代码
void foo(T t);
……
T t;
foo(t); // 编译器会在栈上构造一个临时对象,并将t拷贝过去
另外有种写法也是常见的错误:
void foo(T& t);
……
const T t;
foo(t); // 为了防止在foo中修改t,编译器也会在栈上构造一个临时对象
将对象作为函数返回值也是一种产生临时对象的现象:
string T() { ……; }
……
string s;
s = foo();
典型的是实现operator +,因为按照其语义,必须返回一个传值的对象;所以在使用 string的 + 时要注意,最好用 +=或者 append() 等。
类似vector在重新分配空间时,也会导致临时对象的产生:
比如以前是100个元素,现在需要插入10个元素,那么vector会分配至少110元素的空间,将这100个元素拷贝过去,接着在这100个元素原有的空间上调用其析构函数,总共会有110次拷贝构造函数和100次析构函数的调用。
正确的代码
尽量使用引用传递参数,如果不允许修改参数则使用const,例如:
void foo(T& t) 或者 void foo(const T& t)
1.1.1.7 其它提高速度的技巧
1、 使用位域来节省空间,比如:
struct BillingRec
{
……
unsigned call: 3; //three bits
unsigned tariff: 2; //two bits
};
2、当函数的参数太多的时候,可以使用一个类或者结构来封装这些参数;
3、将不改变的数据声明为常量;
4、使用仿函数而非函数指针,因为仿函数可以做inline展开;
5、禁止RTTI和异常处理;
1、 注意字节对齐问题
class CLarger // 占用 20字节的类
{
bool b1;
int i1;
bool b2;
int i2;
bool b3;
};
class CSmaller // 占用 12 字节的类
{
int i1;
int i2;
bool b1;
bool b2;
bool b3;
};
- C++的一些优化操作
- c一些经典的操作
- c字符串的一些操作
- 一些c的字符串操作
- iOS性能优化的一些操作(补充)
- surfaceview刷新操作的一些优化建议
- MYSQL数据库的一些优化操作
- C代码优化的一些方法
- C\C++代码优化的一些建议
- C语言 链表的一些操作
- C的一些基本指针操作
- c语言位操作的一些注意事项
- C的一些基本指针操作
- C中的一些关于字符串的操作
- Pro*C的一些基本操作
- C语言的一些简单操作
- C/C++单链表的一些操作
- [C#]窗口的一些简单操作
- 端口
- 正确地做事与做正确的事同样重要
- Android系统的Binder机制
- Android禁止横屏竖屏切换
- Python备份CSDN博客
- C++的一些优化操作
- 安卓巴士Android开发神贴整理
- 3.2电话号码对应英语单词
- 内核初步学习
- MS SQL基本语法及实例操作
- 写给Linux内核新手-关于Linux内核学习的误区(转载)
- myweb框架简单说明
- Linux下软件的安装与卸载(转贴)
- 64位系统提示“未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序”错误解决方法