1 优化概述
1.1 用好的编译器,并用好编译器
1.2 选用支持C++11的编译器
1.3 选用更好的算法
1.4 选择最优算法对性能优化效果最大
1.5 使用更好的库
1.6 减少内存分配和复制
1.7 移除计算
1.8 使用更好的数据结构
1.9 提高并发性
1.10 优化内存管理
2 影响优化的计算机行为
2.1 访问内存开销大
2.2 非对齐访问慢
2.3 访问频繁使用的内存地址速度快
2.4 访问相邻地址快
2.5 一个函数运行于上下文比测试套件中慢
2.6 访问线程间共享数据慢
2.7 计算比决定快
2.8 每个程序都会与其它程序竞争计算机资源
2.9 如果程序在负载高峰时执行,测量性能时也要加载负载
2.10 每一次赋值,函数参数初始化,函数返回,都会调用构造函数,这个函数可能隐藏大量未知代码
2.11 有些语句隐藏大量计算,外表看不出开销
2.12 并发线程共享数据时,同步代码降低并发量
3 测量性能
3.1 必须测量性能
3.2 做出可测试的预测并记录预测
3.3 记录代码修改
3.4 如果每次都记录了实验内容,那么可以快速重复实验
3.5 一个程序会花费90%时间去执行10%的代码
3.6 只有正确且精确的测量者准确的测量
3.7 分辨率不是准确性
3.8 只进行有明显效果的性能改善,开发人员就无需担心方法论的问题
3.9 计算一条C++语句对内存读写次数,可以估算出一条C++语句的性能开销
4 优化字符串的使用:案例研究
4.1 由于字符串是动态分配内存的,因此它们的性能开销非常大。它们在表达式中的行为与值类似,它们的实现方式中需要大量的复制。
4.2 将字符串作为对象非值可以降低内存分配和复制的频率
4.3 使用复合赋值操作避免临时字符串
4.4 result = result + s[i]; 改成 result += s[i]; 改成
4.5 为字符串预留内存空间可以减少内存分配的开销
4.6 将字条串的常量引用传递给函数与传递值 相比结果几乎一样,但更加高效
4.7 函数返回通过引用返回,比返回值更高效
4.8 即使只是有时候会减少内存分配,仍然是一种优化
4.9 换更高效的算法
4.10 标准库是为通用用途实现的,简单,但并不高效
5 优化算法
5.1 常量时间算法可能开销是O(n)
5.2 混合使用多种高效算法可能导致整体运行时间变为O(n2)或是更差
5.3 对于表项小于4的表,什么查找算法都一样
6 优化动态分配内存的变量
6.1 动态分配内存是最大的“性能杀手”
6.2 只要知道如何减少对内存管理器的调用,开发人员就是个高效的性能优化专家
6.3 通过提供::operator new() 和::operator delete(),可以整体地改变程序分配内存的方式
6.4 通过替换malloc和free()可以整体改变程序管理内存的方式
6.5 指针实现了动态变量所有权的自动化
6.6 共享了所有权的动态变量更加昂贵
6.7 静态创建类实例
6.8 静态创建类成员并且在有必要时采用两段初始化
6.9 让主指针拥有动态变量,无主指针替代共享所有权
6.10 让输出函数免复制
6.11 实现移动语义
6.12 扁平数据结构更好
7 优化热点语句
7.1 除非有一些因素放大了语句的性能开销,否则不值得进行语句级别的性能优化,因为带来的提升不大
7.2 循环次数就是放大位数,所以留心循环体中的语句、函数调用
7.3 有些语句(赋值,初始化,函数参数计算)中包含了隐藏的函数调用
7.4 操作系统函数调用是昂贵的
7.5 一种有效移除函数的方法是内联
7.6 现在已经不需要impl了,当初的初衷是为了缩短编译时间
7.7 double比float快
8 使用更好的库
8.1 C++标准库之所以提供这些函数和类,是因为要么无法通过其它方式提供,要么这些函数广泛应用于多种操作系统上
8.2 标准库也有bug
8.3 没有一种“完全符合标准的实现”
8.4 标准库不如最好的原生函数高效
8.5 当要升级库时,尽量只进行最小的改动
8.6 接口的稳定性是可交付的库的核心
8.7 对库进行性能优化时,测试用例非常关键
8.8 设计库与设计其他C++代码是一样的,只是风险更高
8.9 不需要超过三层继承
8.10 不超过三层嵌套函数调用
9 优化查找和排序
9.1 尝试手工编码定制,效率比标准库高
10 优化数据结构
10.1 斯特潘诺夫的标准模板库是第一个可复用的高效容器和算法库
10.2 各容器类的大O标记性能并不能反映真实情况
10.3 在进行插入、删除、遍历和排序操作时,vector最快
10.4 使用lower_bound查找已排序vector速度可以与map匹敌
10.5 deque只比list快一点
10.6 unordered_map比map更快,但快不到一个数量级
10.7 网上有丰富的类似标准库的容器资源
11 优化IO
11.1 不论哪个网站,互联网上的快速IO代码不一定快
11.2 增加readbuf可以提高性能几个百分点
11.3 endl会刷新缓冲,开销昂贵
12 优化并发
12.1 如果没有竞争,那么一个多线程C++程序具有顺序一致性
12.2 社区认为显式同步和共享变量是一个糟糕的主意
12.3 在临界区执行I/O操作无法优化性能
12.4 可运行线程数量应该少于或等于核心数量
12.5 理想竞争一块短临界区的核心数量是两个
13 优化内存管理
13.1 相比于内存管理器,应该先看看其它地方还有没有更好性能改善的机会
13.2 替换默认管理器对整体运行性能提升最多30%
13.3 为申请相同内存块的管理器很容易编写,效率也很高
13.4 可以在类级别重写new
13.5 编写一个自定义内存管理器可以提高程序性能,但效果不明显