软件工程师的首要任务是经济且高效地开发可维护且合格的软件。
——Jon Louis Bentley, Writing Efficient Programs (Prentice Hall,1982)
即使过了40年,Jon的这句名言也仍然是软件领域的金句。任何软件工程师的最终目标都是开发合格的、能在其生命周期内物尽其用的软件产品。不过遗憾的是,并非每个开发者都能意识到软件成本的重要性。现实中更残酷的是,软件的研发成本往往被低估。例如,Rockstar公司曾斥资1.375亿美元,250名工程师耗时5年,开发出了广受欢迎的游戏——《侠盗猎车手5》( Grand Theft Auto 5 )( https://oreil.ly/0CRW2 )。再比如,为了开发可用性高的商用操作系统,苹果公司在2001年首次发布macOS( https://oreil.ly/hQhiv )之前,就已耗费超过5亿美元,在当时称得上是“巨资”。
正因软件研发的成本很高,所以将精力集中在重要环节显得至关重要。在理想情况下,谁也不想将珍贵的研发时间和精力浪费在不必要的事情上,例如,花费数周时间做代码重构并不能客观地降低代码复杂性,或者对很少使用的功能做深度优化。因此,软件研发行业的新模式层出不穷,以追求高效的开发过程。比如,让我们拥抱不断变化的需求的敏捷看板(Agile Kanban)、移动开发领域出现的专用编程语言Kotlin,或者网页开发框架React。很多领域的工程师都在不断地创新,因为低效注定会增加成本。
目前在软件研发领域还有更难的问题,那就是还需要考虑到未来的成本。有资料显示,软件的运维成本甚至高于初始研发成本( https://oreil.ly/59Zqe )。诸如代码变更、bug修复、事件响应、安装以及计算成本(包括耗电量)等必要事项,只是我们计算软件总拥有成本(TCO)的其中几环。敏捷研发模式通过频繁的发版和快速的反馈,可以帮助计算此成本。
然而,单纯地从软件研发过程中将效率等优化工作剔除,会带来TCO的提升吗?在很多场景下,为应用程序的执行多等待几秒不是什么大问题。最重要的是,硬件成本在逐月递减,而运行速度却在逐月递增。2022年,购买拥有十几GB内存的智能手机并不困难,2TB的固态硬盘只有手指般大小,但读写吞吐量却能达到惊人的7GBps( https://oreil.ly/eVcPQ ),甚至连家用计算机也能达到非常高的性能分数。目前8个及以上CPU每秒能执行数十亿次循环运算,加上2TB内存,应用程序在这样的硬件上运行能显著提升运行效率。有了这样的硬件加持,我们就能不做优化工作了吗?
与人相比,机器正在变得越来越廉价;任何不考虑这一点的关于计算机效率的讨论都是目光短浅的。“效率”涉及整体成本的降低——不仅节省了程序生命周期中的机器时间,还包括开发者和用户花费的时间。
——Brian W.Kernighan和P.J.Plauger, The Elements ofProgramming Style (McGraw-Hill,1978)
毕竟,优化程序的时间和空间复杂度是一个复杂的话题。特别是当你初出茅庐的时候,你可能会在一些并没有显著效果的优化工作上面浪费许多时间。即使我们开始关注代码引入的延迟问题,Java虚拟机(JVM)或Go编译器之类的组件也会帮助我们来做优化。你还可能会花费更多的时间在一些棘手的问题上,比如在当前的硬件基础上再进行无关的优化,那会牺牲掉程序的可靠性和可维护性。这些例子只是导致工程师将性能优化视为开发工作最低优先级的几个原因。
不幸的是,与每一种极简思想一样,将性能视为第一要义也存在一定的风险。不过不用担心,在本书中,笔者不会要求你去度量每行代码的执行纳秒数或其在内存中被分配的每一个bit,也不会试图鼓励你将性能优化放在开发工作的首位。
然而,刻意地推迟性能优化工作和犯一些愚蠢的错误之间是有明显区别的,因为这会导致程序运行效率低下。俗话说,“求全则毁”( https://oreil.ly/OogZF ),但我们也要先找到其中的平衡点。因此,笔者希望作为软件工程师的读者在思考应用程序性能的时候能有所改变,它可以促使你在编程和研发管理周期中养成简单却有效的习惯。有关数据显示,在研发周期中需要尽早判断何时应该忽略性能问题,什么情况下应该延期解决程序的性能问题,在遇到必须做性能优化这道坎时,需要明确在哪里做优化,以及何时优化结束,以达到预期效果。
在1.1节中,笔者将剖析“性能”一词的深层次含义。在1.2节中,将围绕效率和性能的五个常见误区展开详细讨论,这些误区需要从开发者潜意识中连根拔除。此外,你还将了解到,对于效率的思考并不仅限于“高性能”软件,这是一个基本能力。
本书有些章节(比如本章和第3章)以及其他章节的部分内容与编程语言无关,这些经验对于非Go技术栈的开发者同样适用。
最后,在1.3节中,你将了解到为什么关注效率能让我们在不牺牲时间和其他软件质量的前提下,有效地进行性能优化。本章内容会让你感觉偏向理论,但请相信笔者,了解本章内容将使你养成对于性能优化、算法优化、代码优化的编程意识,或许还能帮助你说服产品经理和领导,让他们知道你对于效率的关注对整个项目是有益的。
下面我们从了解效率的定义开始本书的阅读之旅。