c++ advise

 

c++ vector指定大小,直接用下标而非pushback

指定大小,避免vector在添加新元素时频繁重新分配内存和拷贝数据。

每次只使用push_back添加元素,vector会频繁的重新分配内存并拷贝数据来维持连续存储,影响效率。

用emplace back替代pushback

push_back在添加元素时,需要先构造元素,再移动或拷贝到vector的末尾。

而emplace_back直接在vector末尾构造传入的参数为新的元素,避免了拷贝或移动构造的开销。

所以当添加自定义类对象到vector时,使用emplace_back可以提高效率:

用乘法代替除法 用& 代替%

int x = a / b; 
// 乘法运算
int x = a * (1.0/b);

CPU对除法的算数运算速度相对较慢,特别是浮点数除法需要处理规格化、特殊情况等,计算复杂度较高。

而乘法计算简单快速,只需要执行基本的算数运算

// 取余运算
int x = a % 32;

// 位运算    
int x = a & 31;

取余运算需要执行复杂的除法运算后再取余数,计算量大。

位运算直接通过位的与操作就可以实现相同的功能,只需要一步位操作,计算量小很多。

此外,CPU也是通过直接的位操作来实现位运算,不需要经过复杂的算数逻辑单元,速度快。

减少循环体内的计算,内存访问和分支判断

  1. 减少循环内计算

循环体内的计算会重复执行多次,复杂计算会带来更高的循环开销。减少循环内运算量,例如提前取值、简化等可以显著提升循环效率。

  1. 减少内存访问

由于存储器访问速度较慢,循环内重复访问会形成瓶颈。采用缓存、削减访问、读入批量数据等方式可以减少内存访问次数。

  1. 减少分支判断

分支预测失败会导致流水线清空等。减循环内复杂判断,采取顺序访问、简化判断等可以提升效率。

常调用函数inline化

  1. 省去函数调用开销

普通函数调用需要入栈出栈等操作,而内联函数将函数体插入调用处,避免了这些开销。

  1. 有利于编译器优化

内联函数代码可与周围代码一同进行优化,提高Cache使用率,方便优化。

  1. 防止重复计算

对于执行体简单而频繁调用的函数,内联可避免重复计算。

所以对性能关键的热点函数,如在循环内调用,都应考虑内联。

内联通常在类内部访问器方法、蹦床函数等情况使用。不宜过度使用,以免代码膨胀。

查表代替计算

例如计算 cos(x),x取整数