软件优化工作有许多基础方法,这里介绍了4大块共22个小方法。
packing:在一个machine word(字节\dw)中存储多于一个的数据
encoding:用更少的字节存储相同的数据
例:int型的 1912 比字符串型的 1912 占据空间小、
在数据结构里加一些信息让基础动作更简便
例:在一个链表后append另一个链表,存储一个指向尾结点的指针,让append更快。
对一些要用到的数据进行预计算,类似于动态规划
例:事先计算杨辉三角,以计算二项式系数
前面的计算结果不删掉,一遍后续的计算能用,有点类似简陋版的动态规划。
将结构化的数据紧凑化。改变数据结构,避免存储与计算 0。
例:稀疏矩阵的存储:用一个二维数列存储每个元素的值与在列的位置,用一个一维数组存储每行的数量(存储起始位置,存储指针)。
例:将图简化。
将所有的常数计算都放到编译阶段
变量计算可以简化,目的,更少的基本计算语句执行
例 a=b+c d=c+ e f=a-d 变为 a=b+c d=c+e f=b-e
同相同效果的但是计算量更小的运算符符号替代。
例:比较sqrt(a)<b ==== a<b^2,开根号的消耗比平方大
达到条件时提早停止循环,例如冒泡排序中设置停止条件
条件判断语句中,可能有多个分支,越常见的分支放到最前面(有点类似哈夫曼树)
创建提早成功、退出条件,这些退出条件的计算比较简单
深度大于1的条件判断树,将其combine成深度为1的条件判断树,用 switch 等
loop-invariant code motion
将循环中常见计算等每次相同的计算外提
哨兵,如循环中的flag,作退出条件
循环展开
例:一个循环,12 * 1一个语句 改成 4 * 3个语句
优点:循环中更少的跳转指针的数量,可以获得更多的编译优化
如果可以,将两个循环 合并 到一个循环中
规定合理的循环边界
例:
flag = 30;
for(int i=0;i<flag;i++){
if(i<20)
do something
}
把n改为20
使用 内联函数 ,让运行速度赶上宏指令
尾递归优化,原理是编译器会把尾递归变成一个循环,防止爆栈
https://zhuanlan.zhihu.com/p/36587160
在某些时段用更有效率的代码代替原有函数
例:归并函数 优化成 归并插入函数
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删