再写if-else,就把你消灭

if-else的两宗罪

实际上,我们并不是杜绝if-else,而是建议少用。

怎么干掉if-else

第一种方法:排非策略

优化前:

优化后:

第二种方法:三元运算符

三元运算符相比if-else来说,只需一行语句,代码简练精炼。

当然,也有工程师认为,不要过度关注if-else的数量和层数,而是要关注语义是否清晰,单纯减少if-else但又让代码更难阅读反而是画蛇添足。

翻开市面大部分编程教程,最早能够接触到的条件语句基本都是if-else。

作为高级编程语言都有的必备功能,if-else在嵌入式编程过程中几乎是必用。但任何东西都有限度,滥用它,只会让代码逐渐抽象、离谱,最后成为“屎山”。

接手项目的程序员叫苦不迭;忍无可忍的CTO对着满屏的if-else终于下定决心,下次逮着谁再写if-else,罚款1000块。

那么,为什么if-else这么不受待见,怎么干掉它,不滥用它?

if-else的两宗罪

实际上,我们并不是杜绝if-else,而是建议少用。

究其原因,一共有两点:一是影响程序的运行效率;二是影响代码的可读性,增大运维难度。

目前,大部分人的观点是if-else的分支预测(Branch Prediction)会降低执行效率。

CPU执行一条指令分为IF、ID、EX、WB四个阶段。分阶段执行(也就是pipeline流水线执行)会先给出一个预测结果,让流水线直接执行,执行对了则继续;执行错了,则退回去重新执行,直到对为止。

比如说,在这样的代码中:

int a = 0;


a += 1;


a += 2;


a += 3;

CPU并非运行完a=0后执行a +=1,而是在运行a=0读执行后,马上运行a +=1的读执行。

流水线执行的好处很多,但对if语句来说,就会开启分支预测,如果预测失败,就会影响执行时间。但未对数组排序前提下,分支预测大概率会失败,从而导致指令执行结束后重新读取下一条指令,无法发挥流水线效果。说白了,只有分支预测一直成功,CPU执行效率才会大幅提升。

不过,需要强调的是,所有带有跳转结构的语句比如if、switch、for都会出现这种情况。而且,现代CPU性能远超过去,只有存在巨大量if-else情况才会影响性能,即便出现性能问题,也得在一个结构清晰的架构上分析性能是不是才能更好的定位,实在不行也可以把这段替换成汇编。

所以相比来说,导致程序运行效率下降并非if-else的最大原罪,而是影响可读性。

代码本质是给人看的,人得能看懂,从上到下扫一下大概就明白设计意图、思路就是好代码,这样的代码也是基本没有if-else的,如果还需要反复从上看到下,再从下看到上,这样的代码即使这次看懂隔一段时间也会忘记的。也就是“高内聚,低耦合”。

许多工程师在接手老项目时,时常会收到扑面而来的是,代码中可能会充斥着大量的 if/else ,嵌套 6、7 层,一个函数几百行,多层判断让人无从下手,绝望、愤怒、无奈喷涌而出,而且这样的惨案已经不止发生过一次。总结成一句话就是,看死人。

这种代码风格早在几十年前就被国外所批判,并被称之为“箭头代码”(Arrow-code)

实际工作中,我们能见到一个方法包含10个、20个甚至更多的逻辑分支的情况。而更为致命的情况就是if-else的多层嵌套。

代码的多层嵌套拥有很大隐患,也给代码库增加了很多不必要的复杂性。

人脑一次只能处理几件不同的事情,因此当面临需要深入分析多个代码层级时,很容易忘记上一层的关键逻辑,导致一些不必要的错误。

还是那句话,代码是给人看的,我们的业务流程已经足够复杂了,多层嵌套还会进一步增加了其复杂度。

遇到这种情况怎么办,不要慌,直接干掉if-else。

怎么干掉if-else

第一种方法:排非策略

优化前:

优化后:

第二种方法:三元运算符

三元运算符相比if-else来说,只需一行语句,代码简练精炼。

示例一:

示例二:

第三种方法:使用switch、key-value和Map

Switch显然更简单,而且,不同的条件分支之间没有嵌套,并且它们彼此独立,逻辑很清楚。不过,代码本身也会有点多。

此时key- value和Map就是很好的方法。

第四种方法:逻辑与运算符

有些时候我们可以使用逻辑与运算符来简化代码。

第五种方法:使用 includes 处理多重条件

第六种方法:责任链模式和策略模式

责任链模式是实现了类似“流水线”结构的逐级处理,通常是一条链式结构,将“抽象处理者”的不同实现串联起来。策略模式的目的是将算法的使用与定义解耦,能够实现根据规则路由到不同策略类进行处理。

当然,并不是说用if-else就很low,用设计模式就高大上,二者擅长场景不同,if-else足以满足大部分日常需求的开发,且简单、灵活、可靠,而设计模式则是为了更简洁、拓展性好、性能更优、可读性更好等。

抛弃else吧,你会打开新世界

当然,无论哪种重构方法,都只是优化。归结起来,最简单的方法就是在写代码之处,抛弃else。抛弃else就可以减少嵌套层数,有效降低代码复杂度。让代码更简单,结构更清晰,更容易维护。

如果我们抛弃if-else块中的else并优先处理这块逻辑。先处理小的边界情况,如果必要的话提前返回;否则,将主流程保留在函数的最外层。

同样的思路也可以应用于处理多个边缘情况:

由于边界情况在函数的顶部得到了处理,开发者在后续添加新代码时不太可能忽略这些情况,从而降低了引入错误的风险。处理边缘情况并早期返回可以减少不必要的计算,从而可能提高代码的执行效率。

简化的代码结构更容易被同事理解,从而使代码审查过程更顺畅,减少潜在错误和不良事件传播。

当然,也有工程师认为,不要过度关注if-else的数量和层数,而是要关注语义是否清晰,单纯减少if-else但又让代码更难阅读反而是画蛇添足。乱优化if-else没什么好处,应该优化的是本身条件的分割,把流理清楚后if-else比啥都清晰。

所以最好的做法是写一篇详细文档,从最原始的数学模型开始,表明采取何种计算策略,策略如何推倒,然后给整个方法加上注释附上文档地址,并且在每个分支的地方加上注释指明对应到文档中哪个公式。

总结起来,就是一句话:没有对与错,而是要看场景,任何时候,只要能让代码更易读和维护,就成功了。

参考文献

[1] 非典型技术宅:为什么建议少用if语句,不是运行效率!.2021.5.4.https://mp.weixin.qq.com/s/CHASap6dHJP_Cn2nL6aMiA

[2] CSDN:现在开始,把代码里的 ‘else’ 丢掉!”.2023.10.04.https://mp.weixin.qq.com/s/rRlV_sresmxGDFt8RMFraQ

[3] 知乎:优化代码中大量的 if/else ,你有什么方案?

[4] 前端有道:代码中大量的if/else,你有什么优化方案?.2021.5.21.https://mp.weixin.qq.com/s/LY-6IwOqXiBiN_TY0aq_6Q

[5] 阿里云开发者:如何优化你的if-else?来试试“责任树模式”.2021.1.26.https://mp.weixin.qq.com/s/Wib0Ly45te00HMUnIG-tbg

本文来自微信公众号:电子工程世界(ID:EEworldbbs),作者:付斌

声明: 该内容为作者独立观点,不代表新零售资讯观点或立场,文章为网友投稿上传,版权归原作者所有,未经允许不得转载。 新零售资讯站仅提供信息存储服务,如发现文章、图片等侵权行为,侵权责任由作者本人承担。 如对本稿件有异议或投诉,请联系:wuchangxu@youzan.com
(0)
上一篇 2023年12月29日
下一篇 2023年12月29日

相关推荐

  • 水温80度:AI行业真假繁荣的临界点

    我们从来没拥有过这么成功的AI主导的产品。

    (这种分析统计并不那么准,但大致数量级是差不多的)

    这两个产品碰巧可以用来比较有两个原因:

    一个是它们在本质上是一种东西,只不过一个更通用,一个更垂直。

    蓝海的海峡

    未来成功的AI产品是什么样,大致形态已经比较清楚了,从智能音箱和Copilot这两个成功的AI产品上已经能看到足够的产品特征。

    未来科技 2024年6月5日
  • ChatGPT、Perplexity、Claude同时“罢工”,全网打工人都慌了

    美西时间午夜12点开始,陆续有用户发现自己的ChatGPT要么响应超时、要么没有对话框或提示流量过载,忽然无法正常工作了。

    因为发现AI用久了,导致现在“离了ChatGPT,大脑根本无法运转”。”

    等等,又不是只有一个聊天机器人,难道地球离了ChatGPT就不转了。

    大模型连崩原因猜想,谷歌躺赢流量激增6成

    GPT归位,人们的工作终于又恢复了秩序。

    未来科技 2024年6月5日
  • ChatGPT宕机8小时,谷歌Gemini搜索量激增60%

    ChatGPT一天宕机两次

    谷歌Gemini搜索量激增近60%

    ChatGPT在全球拥有约1.8亿活跃用户,已成为部分人群工作流程的关键部分。

    过去24小时内提交的关于OpenAI宕机的问题报告

    图片来源:Downdetector

    ChatGPT系统崩溃后,有网友在社交媒体X上发帖警告道:“ChatGPT最近发生的2.5小时全球中断,为我们所有依赖AI工具来支持业务的人敲响了警钟。

    未来科技 2024年6月5日
  • ChatGPT、Perplexity、Claude同时大崩溃,AI集体罢工让全网都慌了

    接着OpenAI也在官网更新了恢复服务公告,表示“我们经历了一次重大故障,影响了所有ChatGPT用户的所有计划。Generator调查显示,在ChatGPT首次故障后的四小时内,谷歌AI聊天机器人Gemini搜索量激增60%,达到327058次。

    而且研究团队表示,“Gemini”搜索量的增长与“ChatGPT故障”关键词的搜索趋势高度相关,显示出用户把Gemini视为ChatGPT的直接替代选项。

    未来科技 2024年6月5日
  • 深度对话苹果iPad团队:玻璃的传承与演变

    iPad最为原始的外观专利

    没错,这就是iPad最初被设想的样子:全面屏,圆角矩形,纤薄,就像一片掌心里的玻璃。

    2010年发布的初代iPad

    好在乔布斯的遗志,并未被iPad团队遗忘。

    初代iPad宣传片画面

    乔布斯赞同这一想法,于是快速将资源投入平板电脑项目,意欲打造一款与众不同的「上网本」,这就是iPad早年的产品定义。

    iPad进化的底色

    苹果发布会留下过很多「名场面」,初代iPad发布会的末尾就是一例。

    未来科技 2024年6月5日
  • 底层逻辑未通,影视业的AI革命正在褪色…

    GPT、Sora均为革命性产品,引发了舆论风暴,但它在上个月发布的“多模态语音对谈”Sky语音,却由于声音太像电影明星斯嘉丽·约翰逊,被正主强烈警告,被迫下架。

    华尔街日报也在唱衰,认为“AI工具创新步伐正在放缓,实用性有限,运行成本过高”:

    首先,互联网上已经没有更多额外的数据供人工智能模型收集、训练。

    03、

    如果说训练“数字人”、使用AI配音本质上瞄向的仍是影视行业固有的发展方向,那么还有另外一群人试图从根本上颠覆影视行业的生产逻辑和产品形态。

    但分歧点正在于此,电影公司希望通过使用AI技术来降低成本,但又不希望自己的内容被AI公司所窃取。

    未来科技 2024年6月5日
  • KAN会引起大模型的范式转变吗?

    “先变后加”代替“先加后变”的设计,使得KAN的每一个连接都相当于一个“小型网络”, 能实现更强的表达能力。

    KAN的主要贡献在于,在当前深度学习的背景下重新审视K氏表示定理,将上述创新网络泛化到任意宽度和深度,并以科学发现为目标进行了一系列实验,展示了其作为“AI+科学”基础模型的潜在作用。

    KAN与MLP的对照表:

    KAN使神经元之间的非线性转变更加细粒度和多样化。

    未来科技 2024年6月5日
  • 这个国家,也开始发芯片补贴了

    //mp.weixin.qq.com/s/tIHSNsqF6HRVe2mabgfp6Q
    [4]中国安防协会:欧盟批准430亿欧元芯片补贴计划:2030年产量占全球份额翻番.2023.4.19.https。//mp.weixin.qq.com/s/VnEjzKhmZbuBUFclzGFloA
    [6]潮电穿戴:印度半导体投资大跃进,一锤砸下1090亿,政府补贴一半.2024.3.5https。

    未来科技 2024年6月5日
  • 大模型的电力经济学:中国AI需要多少电力?

    这些报告研究对象(数字中心、智能数据中心、加密货币等)、研究市场(全球、中国与美国等)、研究周期(多数截至2030年)各不相同,但基本逻辑大同小异:先根据芯片等硬件的算力与功率,计算出数据中心的用电量,再根据算力增长的预期、芯片能效提升的预期,以及数据中心能效(PUE)提升的预期,来推测未来一段时间内智能数据中心的用电量增长情况。

    未来科技 2024年6月5日
  • 你正和20万人一起接受AI面试

    原本客户还担心候选人能否接受AI面试这件事,但在2020年以后,候选人进行AI面试的过程已经是完全自动化的,包括面试过程中AI面试官回答候选人的问题,AI面试官对候选人提问以及基于候选人的回答对候选人进行至多三个轮次的深度追问。

    以近屿智能与客户合作的校验周期至少3年来看,方小雷认为AI应用不太可能一下子爆发,包括近屿智能在内的中国AI应用企业或许要迎来一个把SaaS做起来的好机会。

    未来科技 2024年6月4日