C++性能优化实战指南_c程序性能优化

C++性能优化实战指南_c程序性能优化

编码文章call10242025-02-10 11:19:1216A+A-


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 编写一个自定义内存管理器可以提高程序性能,但效果不明显

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4