File: fastmif.txt
Name: 正确的优化分段函数形式的多重分支代码
Author: zyl910
Blog: http://blog.csdn.net/zyl910/
Version: V1.00
Updata: 2006-10-13
一、基本代码
有时候,我们会碰上这样的多重分支代码:
char szbuf[10];
if (score >= 90) strcpy(szbuf, "优");
elseif (score >= 80) strcpy(szbuf, "良");
elseif (score >= 60) strcpy(szbuf, "及格");
else strcpy(szbuf, "不及格");
这样的代码无疑是很低效的,怎么优化呢?
二、错误的优化
很多书上说可以根据频率分布来优化代码,比如及格的人最多时,这样编写代码:
char szbuf[10];
if (score >= 60 && score < 80) strcpy(szbuf, "及格");
elseif (score >= 80 && score < 90) strcpy(szbuf, "良");
elseif (score >= 90) strcpy(szbuf, "优");
else strcpy(szbuf, "不及格");
可以看出,这样做实际上增加了判断次数。只有在分支极多时,该优化方案才比上一个好。
三、正确的优化
现在都是做整数比较,速度非常快的,反而会因判断之后的跳转指令堵塞流水线而影响效率。所以正确的优化代码应该是这样的:
const char szlist[][10] = {"不及格", "及格", "良", "优"};
char szbuf[10];
int i=0;
i += ( score >= 60 ); // #1
i += ( score >= 80 ); // #2
i += ( score >= 90 ); // #3
strcpy(szbuf, szlist[i]);
当score小于60时,#1、#2、#3均不成立,所以 i = i + 0 + 0 + 0 = i + 0 = 0
当score在[60,80)区间时,#1成立,所以 i = i + 1 + 0 + 0 = i + 1 = 1
当score在[80,90)区间时,#1、#2均成立,所以 i = i + 1 + 1 + 0 = i + 2 = 2
当score大于90时,#1、#2、#3均成立,所以 i = i + 1 + 1 + 1 = i + 3 = 3
最后用索引i从szlist中得到具体数据。
四、全面优化
看出来了吧,对于这种分段函数形式的多重分支代码,可以根据数据特点来优化。所以,我们还可以更进一步,将程序改成表格驱动的形式:
const char szlist[][10] = {"不及格", "及格", "良", "优"};
const char idxlist[] = {60, 80, 90};
然后我们在idxlist表中搜索score,得到索引,再用索引从szlist得到数据。
这样无论以后的需求如何改变,我们只需要修改这两行代码就行了。
这时,可能会有人问了:如果分支极多怎么办,难道还是一个一个的比较?现在流行面向对象编程,很多时候进行的是对象比较,而对象比较的速度很慢,而现在又搞这么多比较,那不是影响效率吗?
注意我刚才说过什么——“在idxlist表中搜索score”,现在idxlist中的数据是有序的,当然用二分法查找啊!
具体说起来,由于我们在小于60(idxlist[0])时返回0、在大于等于60(idxlist[0])且小于80(idxlist[1])时返回1……所以这实际上是一个插入到有序容器算法,只不过我们只需得到插入位置(索引),并不需要进行插入。
五、总结
对于“一、基本代码”,其平均判断次数是 n/2,即 O(n)。
对于“三、正确的优化”,其平均判断次数是 n-1,即 O(n)。运算复杂度与上一个一样,但是由于它避免了跳转,所以在项目较少时,该代码的效率最高。
对于“四、全面优化”,由于它采用了二分法查找,其运算复杂度为 O(logn)。在项目很多时,它的效率最高。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库