互联网
类型
8.0
豆瓣评分
可以朗读
语音朗读
307千字
字数
2018-01-01
发行日期
展开全部
主编推荐语
本书精选作者在近30年编程生涯中频繁使用的技术和能够带来能提升效果的技术,旨在让读者在提升C++程序的同时,思考软件优化之美。
内容简介
书中主要内容包括:代码优化的意义和总原则,与优化相关的计算机硬件背景知识,性能分析方法及工具,优化字符串的使用,算法、动态分配内存、热点语句、查找与排序等等的优化方法。
《C++性能优化指南》适合所有C++程序员,也可供其他语言的程序员优化代码时作为参考。
目录
- 版权信息
- 版权声明
- O'Reilly Media, Inc. 介绍
- 业界评论
- 前言
- 为本书中的代码致歉
- 示例代码的使用
- 排版约定
- 第1章优化概述
- 1.1 优化是软件开发的一部分
- 1.2 优化是高效的
- 1.3 优化是没有问题的
- 1.4 这儿一纳秒,那儿一纳秒
- 1.5 C++ 代码优化策略总结
- 1.5.1 用好的编译器并用好编译器
- 1.5.2 使用更好的算法
- 1.5.3 使用更好的库
- 1.5.4 减少内存分配和复制
- 1.5.5 移除计算
- 1.5.6 使用更好的数据结构
- 1.5.7 提高并发性
- 1.5.8 优化内存管理
- 1.6 小结
- 第2章影响优化的计算机行为
- 2.1 C++ 所相信的计算机谎言
- 2.2 计算机的真相
- 2.2.1 内存很慢
- 2.2.2 内存访问并非以字节为单位
- 2.2.3 某些内存访问会比其他的更慢
- 2.2.4 内存字分为大端和小端
- 2.2.5 内存容量是有限的
- 2.2.6 指令执行缓慢
- 2.2.7 计算机难以作决定
- 2.2.8 程序执行中的多个流
- 2.2.9 调用操作系统的开销是昂贵的
- 2.3 C++ 也会说谎
- 2.3.1 并非所有语句的性能开销都相同
- 2.3.2 语句并非按顺序执行
- 2.4 小结
- 第3章测量性能
- 3.1 优化思想
- 3.1.1 必须测量性能
- 3.1.2 优化器是王牌猎人
- 3.1.3 90/10 规则
- 3.1.4 阿姆达尔定律
- 3.2 进行实验
- 3.2.1 记实验笔记
- 3.2.2 测量基准性能并设定目标
- 3.2.3 你只能改善你能够测量的
- 3.3 分析程序执行
- 3.4 测量长时间运行的代码
- 3.4.1 一点关于测量时间的知识
- 3.5 评估代码开销来找出热点代码
- 3.5.1 评估独立的 C++ 语句的开销
- 3.5.2 评估循环的开销
- 3.6 其他找出热点代码的方法
- 3.7 小结
- 第4章优化字符串的使用:案例研究
- 4.1 为什么字符串很麻烦
- 4.1.1 字符串是动态分配的
- 4.1.2 字符串就是值
- 4.1.3 字符串会进行大量复制
- 4.2 第一次尝试优化字符串
- 4.2.1 使用复合赋值操作避免临时字符串
- 4.2.2 通过预留存储空间减少内存的重新分配
- 4.2.3 消除对参数字符串的复制
- 4.2.4 使用迭代器消除指针解引
- 4.2.5 消除对返回的字符串的复制
- 4.2.6 用字符数组代替字符串
- 4.2.7 第一次优化总结
- 4.3 第二次尝试优化字符串
- 4.3.1 使用更好的算法
- 4.3.2 使用更好的编译器
- 4.3.3 使用更好的字符串库
- 4.4 消除字符串转换
- 4.4.1 将 C 字符串转换为 std::string
- 4.4.2 不同字符集间的转换
- 4.5 小结
- 第5章优化算法
- 5.1 算法的时间开销
- 5.1.1 最优情况、平均情况和最差情况的时间开销
- 5.1.2 摊销时间开销
- 5.1.3 其他开销
- 5.2 优化查找和排序的工具箱
- 5.3 高效查找算法
- 5.3.1 查找算法的时间开销
- 5.3.2 当 n 很小时,所有算法的时间开销都一样
- 5.4 高效排序算法
- 5.4.1 排序算法的时间开销
- 5.4.2 替换在最差情况下性能较差的排序算法
- 5.4.3 利用输入数据集的已知特性
- 5.5 优化模式
- 5.5.1 预计算
- 5.5.2 延迟计算
- 5.5.3 批量处理
- 5.5.4 缓存
- 5.5.5 特化
- 5.5.6 提高处理量
- 5.5.7 提示
- 5.5.8 优化期待路径
- 5.5.9 散列法
- 5.5.10 双重检查
- 5.6 小结
- 第6章优化动态分配内存的变量
- 6.1 C++ 变量回顾
- 6.1.1 变量的存储期
- 6.1.2 变量的所有权
- 6.1.3 值对象与实体对象
- 6.2 C++ 动态变量 API 回顾
- 6.2.1 使用智能指针实现动态变量所有权的自动化
- 6.3 减少动态变量的使用
- 6.3.1 静态地创建类实例
- 6.3.2 使用静态数据结构
- 6.4 减少动态变量的重新分配
- 6.4.1 预分配动态变量以防止重新分配
- 6.4.2 在循环外创建动态变量
- 6.5 移除无谓的复制
- 6.5.1 在类定义中禁止不希望发生的复制
- 6.5.2 移除函数调用上的复制
- 6.5.3 移除函数返回上的复制
- 6.5.4 免复制库
- 6.5.5 实现写时复制惯用法
- 6.5.6 切割数据结构
- 6.6 实现移动语义
- 6.6.1 非标准复制语义:痛苦的实现
- 6.6.2 std::swap() :“穷人”的移动语义
- 6.6.3 共享所有权的实体
- 6.6.4 移动语义的移动部分
- 6.6.5 更新代码以使用移动语义
- 6.6.6 移动语义的微妙之处
- 6.7 扁平数据结构
- 6.8 小结
- 第7章优化热点语句
- 7.1 从循环中移除代码
- 7.1.1 缓存循环结束条件值
- 7.1.2 使用更高效的循环语句
- 7.1.3 用递减替代递增
- 7.1.4 从循环中移除不变性代码
- 7.1.5 从循环中移除无谓的函数调用
- 7.1.6 从循环中移除隐含的函数调用
- 7.1.7 从循环中移除昂贵的、缓慢改变的调用
- 7.1.8 将循环放入函数以减少调用开销
- 7.1.9 不要频繁地进行操作
- 7.1.10 其他优化技巧
- 7.2 从函数中移除代码
- 7.2.1 函数调用的开销
- 7.2.2 简短地声明内联函数
- 7.2.3 在使用之前定义函数
- 7.2.4 移除未使用的多态性
- 7.2.5 放弃不使用的接口
- 7.2.6 用模板在编译时选择实现
- 7.2.7 避免使用 PIMPL 惯用法
- 7.2.8 移除对 DDL 的调用
- 7.2.9 使用静态成员函数取代成员函数
- 7.2.10 将虚析构函数移至基类中
- 7.3 优化表达式
- 7.3.1 简化表达式
- 7.3.2 将常量组合在一起
- 7.3.3 使用更高效的运算符
- 7.3.4 使用整数计算替代浮点型计算
- 7.3.5 双精度类型可能会比浮点型更快
- 7.3.6 用闭形式替代迭代计算
- 7.4 优化控制流程惯用法
- 7.4.1 用 switch 替代 if-else if-else
- 7.4.2 用虚函数替代 switch 或 if
- 7.4.3 使用无开销的异常处理
- 7.5 小结
- 第8章使用更好的库
- 8.1 优化标准库的使用
- 8.1.1 C++ 标准库的哲学
- 8.1.2 使用 C++ 标准库的注意事项
- 8.2 优化现有库
- 8.2.1 改动越少越好
- 8.2.2 添加函数,不要改动功能
- 8.3 设计优化库
- 8.3.1 草率编码后悔多
- 8.3.2 在库的设计上,简约是一种美德
- 8.3.3 不要在库内分配内存
- 8.3.4 若有疑问,以速度为准
- 8.3.5 函数比框架更容易优化
- 8.3.6 扁平继承层次关系
- 8.3.7 扁平调用链
- 8.3.8 扁平分层设计
- 8.3.9 避免动态查找
- 8.3.10 留意“上帝函数”
- 8.4 小结
- 第9章优化查找和排序
- 9.1 使用 std::map 和 std::string 的键值对表
- 9.2 改善查找性能的工具箱
- 9.2.1 进行一次基准测量
- 9.2.2 识别出待优化的活动
- 9.2.3 分解待优化的活动
- 9.2.4 修改或替换算法和数据结构
- 9.2.5 在自定义抽象上应用优化过程
- 9.3 优化 std::map 的查找
- 9.3.1 以固定长度的字符数组作为 std::map 的键
- 9.3.2 以 C 风格的字符串组作为键使用 std::map
- 9.3.3 当键就是值的时候,使用 map 的表亲 std::set
- 9.4 使用 <algorithm> 头文件优化算法
- 9.4.1 以序列容器作为被查找的键值对表
- 9.4.2 std::find() :功能如其名,O(n) 时间开销
- 9.4.3 std::binary_search() :不返回值
- 9.4.4 使用 std::equal_range() 的二分查找
- 9.4.5 使用 std::lower_bound() 的二分查找
- 9.4.6 自己编写二分查找法
- 9.4.7 使用 strcmp() 自己编写二分查找法
- 9.5 优化键值对散列表中的查找
- 9.5.1 使用 std::unordered_map 进行散列
- 9.5.2 对固定长度字符数组的键进行散列
- 9.5.3 以空字符结尾的字符串为键进行散列
- 9.5.4 用自定义的散列表进行散列
- 9.6 斯特潘诺夫3的抽象惩罚
- 9.7 使用 C++ 标准库优化排序
- 9.8 小结
- 第10章优化数据结构
- 10.1 理解标准库容器
- 10.1.1 序列容器
- 10.1.2 关联容器
- 10.1.3 测试标准库容器
- 10.2 std::vector 与 std::string
- 10.2.1 重新分配的性能影响
- 10.2.2 std::vector 中的插入与删除
- 10.3 std::deque
- 10.3.1 std::deque 中的插入和删除
- 10.3.2 遍历 std::deque
- 10.3.3 对 std::deque 的排序
- 10.3.4 查找 std::deque
- 10.4 std::list
- 10.4.1 std::list 中的插入和删除
- 10.4.2 遍历 std::list 中
- 10.4.3 对 std::list 排序
- 10.4.4 查找 std::list
- 10.5 std::forward_list
- 10.5.1 std::forward_list 中的插入和删除
- 10.5.2 遍历 std::forward_list
- 10.5.3 对 std::forward_list 排序
- 10.5.4 查找 std::forward_list
- 10.6 std::map 与 std::multimap
- 10.6.1 std::map 中的插入和删除
- 10.6.2 遍历 std::map
- 10.6.3 对 std::map 排序
- 10.6.4 查找 std::map
- 10.7 std::set 与 std::multiset
- 10.8 std::unordered_map 与 std::unordered_multimap
- 10.8.1 std::unordered_map 中的插入与删除
- 10.8.2 遍历 std::unordered_map
- 10.8.3 查找 std::unordered_map
- 10.9 其他数据结构
- 10.10 小结
- 第11章优化 I/O
- 11.1 读取文件的秘诀
- 11.1.1 创建一个吝啬的函数签名
- 11.1.2 缩短调用链
- 11.1.3 减少重新分配
- 11.1.4 更大的吞吐量——使用更大的输入缓冲区
- 11.1.5 更大的吞吐量——一次读取一行
- 11.1.6 再次缩短函数调用链
- 11.1.7 无用的技巧
- 11.2 写文件
- 11.3 从 std::cin 读取和向 std::cout 中写入
- 11.4 小结
- 第12章优化并发
- 12.1 复习并发
- 12.1.1 并发概述
- 12.1.2 交叉执行
- 12.1.3 顺序一致性
- 12.1.4 竞争
- 12.1.5 同步
- 12.1.6 原子性
- 12.2 复习 C++ 并发方式
- 12.2.1 线程
- 12.2.2 promise 和 future
- 12.2.3 异步任务
- 12.2.4 互斥量
- 12.2.5 锁
- 12.2.6 条件变量
- 12.2.7 共享变量上的原子操作
- 12.2.8 展望未来的 C++ 并发特性
- 12.3 优化多线程 C++ 程序
- 12.3.1 用 std::async 替代 std::thread
- 12.3.2 创建与核心数量一样多的可执行线程
- 12.3.3 实现任务队列和线程池
- 12.3.4 在单独的线程中执行 I/O
- 12.3.5 没有同步的程序
- 12.3.6 移除启动和停止代码
- 12.4 让同步更加高效
- 12.4.1 减小临界区的范围
- 12.4.2 限制并发线程的数量
- 12.4.3 避免惊群
- 12.4.4 避免锁护送
- 12.4.5 减少竞争
- 12.4.6 不要在单核系统上繁忙等待
- 12.4.7 不要永远等待
- 12.4.8 自己设计互斥量可能会低效
- 12.4.9 限制生产者输出队列的长度
- 12.5 并发库
- 12.6 小结
- 第13章优化内存管理
- 13.1 复习 C++ 内存管理器 API
- 13.1.1 动态变量的生命周期
- 13.1.2 内存管理函数分配和释放内存
- 13.1.3 new 表达式构造动态变量
- 13.1.4 delete 表达式处置动态变量
- 13.1.5 显式析构函数调用销毁动态变量
- 13.2 高性能内存管理器
- 13.3 提供类专用内存管理器
- 13.3.1 分配固定大小内存的内存管理器
- 13.3.2 内存块分配区
- 13.3.3 添加一个类专用 new() 运算符
- 13.3.4 分配固定大小内存块的内存管理器的性能
- 13.3.5 分配固定大小内存块的内存管理器的变化形式
- 13.3.6 非线程安全的内存管理器是高效的
- 13.4 自定义标准库分配器
- 13.5 小结
- 作者介绍
- 封面介绍
- 看完了
展开全部
出版方
人民邮电出版社·图灵出品
图灵社区成立于2005年6月,由人民邮电出版社投资控股,以策划出版高质量的科技书籍为核心业务,主要出版领域包括计算机、电子电气、数学统计、科普等,通过引进国际高水平的教材、专著,以及发掘国内优秀原创作品等途径,为目标读者提供一流的内容。