《代码大全》代码调整技术
本文针对JAVA列举了《代码大全》中代码调整技术所提到的部分调整方法,以下调整方法也并非在任何地方都适用的,需要结合实际的业务逻辑来考量使用下述方法后代价是否更高,也需要经过严谨的测试来验证性能是否更好。
另一方面,代码调整无可避免地为性能改善的良好愿望付出复杂性、可读性、简单性、可维护性方面的代价,实际开发中需要仔细考量这样的代码调整是否真的被需要。
针对于逻辑
- 在知道答案后停止判断
- &&、||,在第一个判断命中后不在执行后续条件
- break,中断循环
- 按照出现频率来调整判断顺序,命中概率较高的判断提前,例如
if...else if...else语句中,可以将命中率较高的if条件提前,提高命中效率 - 相似逻辑结构之间的性能比较,如果能同时使用
case...when...与if...else if...else...,可通过测试在业务逻辑中使用谁效率更高 - 用查询表代替复杂表达式,枚举所有情况下的值,使用查询表进行缓存,避免每次调用时再执行复杂表达式
- 使用惰性求值,例如单例模式中的懒汉模式
针对于循环
- 尽可能减少循环次数
- 循环条件一致的循环合并
- 尽可能减少循环内部做的工作
- 将结果不会改变的逻辑提取到循环外处理
- 削减运算强度
- 尽可能减少维护循环所做的工作
- 循环展开,例如使用循环给
int[n]赋初始值,可以在每次循环中给两个元素赋值 - 将最忙的循环放在最内层,即将嵌套循环中循环次数最多的循环放在最内层
- 使用哨兵值,例如在
int[n]查找元素等于某个值的下标,可在数组末尾添加哨兵值,由于一定会命中,只需要维护一个下标变量即可,而普通循环查找还需要判断下标是否越界
- 循环展开,例如使用循环给
针对于表达式
- 利用代数恒等式,比如判断n^2与m^2的大小可以转换为比较n与m的大小
- 削弱运算强度,例如乘法转换为加法,乘2除2转换为位运算
- 小心使用系统函数,系统函数通常运行较慢,且提供的精度也并非实际业务中需要的
其他
- 尽可能减少数组维度,能用一维数组就不用二维数组
- 尽可能减少数组引用,避免在同一段逻辑中重复获取数组中的某要一个元素
- 使用辅助索引,比如集合中元素长度使用单独变量维护
- 使用缓存机制