程序优化方法
优化需要通过大量测试来验证一致性、性能,因为并非所有优化都是正确或必要的。从重构程序执行流的角度来讲,优化并不是灵丹妙药,并在不同语言、不同编译器、不同环境、不同任务中表现出巨大的差异。以下的优化方法均仅供参考。
利用短路与哨兵
- 将出现频率高的情况放在优先执行的位置
- 循环中,搜索到目标后立即退出循环
- 循环搜索时,也可以将搜索对象放在数组最后(额外空间),最后检查下标。(本质上是保证不会越界搜索,且保证循环一定正确结束)
优化计算效率
- 程序执行前计算结果,通过常量保存、硬编码、文件保存的方法来避免重复计算
- 尽量减少循环体内的计算工作,可以在之前计算完毕并保存,之后引用
- 公共子表达式应当保存在变量里
- 适当将乘法重写为加法、幂重写为乘法、整数代替浮点数、单精度代替双精度、移位操作代替乘除2、三角恒等式代替三角函数
- 尽量减少数组维度与数组引用
- 多重循环时,将循环次数少的放外层
使用低级语言重写代码
- 使用高级语言完成程序编写
- 进行测试,验证正确性
- 进行程序分析,确定热点代码
- 对热点代码使用低级语言改写
设计恰当的执行控制流
循环
- 循环层数最好不要超过三层
- 短循环可以多使用break、continue等控制,长循环尽量保证唯一出口
- 循环附近不要写重复的代码(修改需要同步修改多处,不便维护)
- for适合与“数量”有关的循环,且不要在内部修改下标;while适合与“条件”有关的循环
- 循环体应当自成子程序,循环条件应当清晰易读
- 多使用for循环,但不要把与循环无关的语句(比如初始化一个不用于循环的变量)放在循环头
- 不要写空循环,将空循环改写成while循环
- 如果一个循环可以做两件事情,把它们拆成两个循环,除非注明在性能上有所提高
- 不要将循环下标作为结果返回。如果需要使用,可以在循环开始前定义新的变量,然后在循环内部对这一变量进行赋值
建表,以提高代码质量
用查表法替换繁琐的if-else判断
使用大量if-else的坏处:
- 不易阅读
- 代码重复度高,无意义
- 对于复杂情况,容易漏条件
- 判断逻辑硬编码在代码中,维护不便
使用查表法的好处:
- 易读
- 代码简洁且高效
- 不会漏掉条件
- 可以将表放在外部文件或者统一放在一起,便于维护;可以在不改变程序的情况下修正运行结果
用法:将要判断的各个参数作为表的维度,将判断结果作为表索引后的结果。
用索引表替换数据表
稀疏的数据表在存储对齐的情况下会浪费大量空间。与之相比,采用索引表可以降低空间浪费量(仍然会产生浪费)。为了进一步减少索引表空间,可以使用阶梯索引表,根据数据的范围(而不是具体的数据值)进行建索引,比如根据百分制成绩计算绩点,建立相应的data-to-key函数,放在数组中。
用结果表替换数学计算结果
考虑到系统函数的精确性,计算速度可能较慢。可以预先手动算出一些数据并建表,计算时直接查表即可,大大提高程序性能。