本章重点讲述提高代码运行速度的方法,同时也对如何减少代码的资源占用给出了一些建议。程序性能通常同代码的速度和资源占用相关,但减小代码资源占用更主要的是通过对类的数据结构的重新设计来实现,而非代码调整。
逻辑
-
在知道答案后停止判断;
-
按照出现频率来调整判断顺序;
-
相似逻辑结构之间的性能比较;
-
用查询表替代复杂表达式;
-
使用惰性求值;
循环
- 将判断外提;
- 合并;
- 展开;
- 进可能减少咋循环内部做的工作;
- 哨兵值;
- 把最忙的循环放在最内层;
- 消减强度。
数据变换
- 使用整型数而不是浮点数;
- 数组维度尽可能少;
- 尽可能减少数据引用;
- 使用辅助索引;
- 字符串长度索引;
- 独立的平行索引结构;
- 使用缓存机制。
表达式
- 利用代数恒等式;
- 削弱运算强度;
- 用加法代替乘法;
- 用乘法代替幂法;
- 利用三角恒等式代换等价的三角函数;
- 用long或int来替代long long整数;
- 用定点数或整型数代替浮点数;
- 用移位操作代替整数乘2或除2;
- 编译器初始化;
- 小心系统函数;
- 使用正确的常量类型;
- 预先算出结果;
- 删除公共子表达式;
子程序
- 将子程序重写为内联;
用低级语言重写代码
用低级语言优化代码的标准方法:
- 用高级语言编写整个应用程序;
- 对程序进行完整的测试,验证其正确性;
- 如果测试后发现需要改进程序性能,就对程序进行分析,确定出热点;
- 把几小段代码在低级语言中重写,以此提高整体性能;
核对表:代码调整方法
同时改善代码执行速度和规模
- [ ] 用查询表替换复杂逻辑;
- [ ] 合并循环;
- [ ] 使用整型变量而非浮点变量;
- [ ] 在编译时初始化数据;
- [ ] 使用正确的常量类型;
- [ ] 预先计算结果;
- [ ] 删除公共子表达式;
- [ ] 将关键子程序代码转化为某种低级语言代码;
仅仅提高代码执行速度
- [ ] 在知道答案后就停止执行判断;
- [ ] 根据各种情况的出现频率对
case
语句和if-then-else
串排序; - [ ] 比较相似逻辑结构的性能;
- [ ] 是用惰性求值;
- [ ] 将循环中的
if
判断转到外部; - [ ] 展开循环;
- [ ] 将循环内部所作的工作量减小到最低限度;
- [ ] 在查找循环中使用哨兵;
- [ ] 把执行最为频繁的循环放在嵌套循环的最里面;
- [ ] 减轻内层循环的强度;
- [ ] 将多维数组改为一维数组;
- [ ] 最大限度减少数组索引;
- [ ] 为数据类型扩充索引;
- [ ] 对频繁使用的值进行缓存;
- [ ] 利用代数恒等式;
- [ ] 降低逻辑和数学表达式得强度;
- [ ] 注意系统调用;
- [ ] 用内联子程序重写代码。
要点
- 优化结果在不同得语言、编译器和环境下有很大得差异。如果没有对每一次得优化进行测量,你将无法判断优化到底是帮助还是损害了这个程序;
- 这一次优化通常不会式最好的。即使找到了效果不错的,也不要停下扩大战果的步伐;
- 代码调整这一话题有点类似于核能,富有争议,甚至会让人冲动。一些人认为代码调整损害了代码可读性和可读性,他们绝对会将其弃之不用。其他人则认为只要有适当的安全保障,代码调整对程序是有益的。如果你决定使用本章所属的调整方法,请务必谨慎行事。