1.理解80-20准则
2.考虑使用懒惰计算法
引用计数 例如string类做法
区别对待读取与写入
懒惰提取 :pointer to implemention的设计思路
懒惰表达式计算
3.分期摊还期望的计算
.提前计算分摊消耗 与上面是一种相反的思想,过度热情计算法
比如说使用缓存(在计算比较频繁或者相同的操作重复进行的时候考虑)
.vector容器内存拓展逻辑
4.理解临时对象的来源
建立一个没有名字的非堆对象会产生临时对象,你可以手动创建 例如 typename(...);
更一般的,在函数调用时进行隐式转换而产生或者是函数返回时产生。
非常量引用不会产生临时对象(函数调用)
5.协助完成返回值优化
返回对象是不可避免的。
应该考虑减少返回对象的开销而不是避免返回对象。
以某种方法返回对象,能让编译器消除临时对象的开销。
即返回constructor argument而不是直接返回对象。
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() + rhs.denominator());
}
建立一个临时对象返回。 这种方法函数内部的临时对象的构造和析构的消耗仍然有,返回对象的构造和析构的消耗也会有。
好处是c++规则允许编译器优化不出现的临时对象,如下:
Rational a = 10;
Rational b(1, 2);
Rational c = a * b;
像这样调用编译器会被允许消除operator*内的临时变量和operator*返回的临时变量,剩下只剩一个构造函数的代价,即构造C。
c不能被消除,因为c是命名对象,命名对象不能被消除。除此之外还可以把这个函数声明为inline消除它的调用开销。
6.通过重载避免隐式类型转换
7.考虑用运算符的赋值形式(op=)取代其单独形式
8.考虑变更程序库
9.理解虚函数,多继承,虚基类和RTTI的代价
了解虚表和虚表指针,即vtbl和vptr. 一个vtbl通常是一个函数指针数组(或者链表)。在类中声明或继承了虚函数,就有自己的
vtbl,vtbl的项目是指向虚函数实现体的指针。
调用虚函数所需的代价基本上与通过函数指针调用函数一样,虚函数本身通常不是性能的瓶颈。
虚函数不能是内联的,