我们程序的目的是让它在任何情况下都能稳定运行。运行速度很快但结果不正确的程序是没有用的。在程序开发和优化过程中,我们必须考虑代码的使用方式,以及影响它的关键因素。通常,我们必须在程序的简单性和运行速度之间做出权衡。今天我们就来说说如何优化程序的性能。1.减少程序运算量1.1示例代码1.2分析代码1.3改进代码2.提取代码公共部分2.1示例代码2.2分析代码2.3改进代码3.剔除循环中的低效代码3.1示例代码3.2分析代码3.3改进代码4.剔除不必要的代码内存引用4.1示例代码4.2分析代码4.3改进代码5.减少不必要的调用5.1示例代码5.2分析代码5.3改进代码6.循环展开6.1示例代码6.2分析代码6.3改进代码7.累积变量,多路并行7.1示例代码7.2分析代码7.3改进代码8.重组转换8.1示例代码8.2分析代码8.3改进代码9条件传递样式代码9.1示例代码9.2分析代码9.3改进代码10.总结1.减少程序计算1.1示例代码for(i=0;i='A'&&s[i]<='Z')s[i]-=('A'-'a');}3.2分析代码接下来我们将测试代码并输入一系列字符串。Lower1代码性能测试当输入字符串长度小于100000时,程序运行时间差别不大。然而,随着字符串长度的增加,程序的运行时间呈指数增长。让我们将代码转换为goto形式。voidlower1(char*s){size_ti=0;if(i>=strlen(s))gotodone;loop:if(s[i]>='A'&&s[i]<='Z')s[i]-=('A'-'a');i++;if(i='A'&&s[i]<='Z')s[i]-=('A'-'a');}比较两个函数,如下图。lower2函数的执行时间已得到显着改善。lower1和lower2代码效率4.消除不必要的内存引用4.1示例代码下面的代码作用是计算数组a中每一行所有元素的和,并存储在b[i]中。voidsum_rows1(double*a,double*b,longn){longi,j;for(i=0;i=v->len)return0;*vval=v->data[idx];return1;}我们将以下面的代码为例开始一个逐步优化程序。voidcombine1(vec_ptrv,data_t*dest){longinti;*dest=NULL;for(i=0;ilen进行比较,防止越界。边界检查是一个好习惯,但每次都这样做效率很低。5.3改进代码我们可以将计算向量长度的代码移到循环外,在抽象数据类型中增加一个函数get_vec_start。该函数返回数组的起始地址。这样循环体中就没有函数调用,而是直接访问数组。data_t*get_vec_start(vec_ptrv){returnv->data;}voidcombine2(vec_ptrv,data_t*dest){longi;longlength=vec_length(v);data_t*data=get_vec_start(v);*dest=NULL;for(i=0;ib[i]){longt=a[i];a[i]=b[i];b[i]=t;}}}9.2代码分析执行命令。处理器中的分支预测在遇到比较指令时预测下一步跳转到哪里。如果预测错误,则需要返回到分支跳出的原始位置。分支预测错误会严重影响程序的执行效率。因此,我们应该编写提高处理器预测准确性的代码,即使用条件移动指令。我们使用条件运算来计算值,然后使用这些值来更新程序状态,如改进后的代码所示。9.3改进代码voidminmax2(longa[],longb[],longn){longi;forfor(i=0;i