
1.1 性能的深意
在探讨为什么软件效率和性能优化如此重要之前,我们必须深刻理解一个已经被滥用的词——性能。在软件工程中,这个词用在很多场景中,不同的场景有不同的意思,所以我们需要从多个角度来理解它。
当有人说“此应用程序性能不佳”时,他一般是指该应用程序运行缓慢[1]。但当同一个人说“Bartek在工作中表现不佳”时(英文performance是个多义词,这里取其“性能”与“表现”之义),并不是说Bartek从工位到会议室走得太慢。根据笔者的观察,在软件研发领域,有相当多的人认为“性能”与”速度”是同义词,而有部分人则认为,它代表软件运行的整体质量,这其实是这个词最初的定义。这种现象被称为“语义扩散”(https://oreil.ly/Qx9Ft),当一个词被更大的群体使用时,它的含义就会与最初的定义产生差异[2]。
计算机性能中的“性能”一词与其他领域的“性能”含义基本相同,它大概描述的是“计算机完成既定任务的表现如何”。
——Arnold O.Allen,Introduction to Computer PerformanceAnalysis with Mathematica(Morgan Kaufmann,1994)
笔者认为Arnold对于性能的描述已经非常接近它的本义了。
注意“性能”一词的使用场景
当我们在阅读文档、代码、错误堆栈或参加技术分享会时,遇到“性能”这个词时要格外注意,必要时请结合语境来理解,以避免曲解作者的意思。
在实际工作当中,性能可以用来衡量软件运行的整体质量,但是它的含义远比我们了解的要深得多。可能你会觉得这有点故弄玄虚,但请思考一下,如果我们想要提升软件研发的综合效益,是不是必须得保证研发过程中保持流畅且高效的沟通呢?
所以,笔者建议在我们真正理解“性能”在具体场景中的含义之前,不要随意使用它,免得引起误解。比如,当你往Github issue中提交错误信息的时候,千万不要随意来一句“性能真差”,而不加以任何的描述说明,这会让项目维护者感到一头雾水。同样,在提交代码变更时,不要在变更日志[3]中用类似“提高了性能”这样的描述,谁会知道你的变更是减少了用户输入错误、优化了内存使用率,还是提升了程序执行速度呢?你至少需要说清楚提高了什么性能,以及是怎样提高的。将场景与细节描述清楚,对大家都好。
笔者在本书中凡是提及该词,都会明确说明上下文。当我们遇到有人使用性能这个词的时候,可以使用图1-1中展示的方式来思考:

图1-1:性能的定义
从原则上来说,“软件性能”一般表示“软件运行情况的好坏”,它由以下三大核心要素支撑。
准确率
表示运行周期中符合预期的任务数量或比率。在软件领域中,通常通过排除掉应用程序产生错误的结果数量来衡量软件性能。例如,We b类系统中已完成且响应状态码为非200的请求数量。
速度
表示执行任务中所有工作的速度快慢与时效性,一般通过观察延迟与吞吐量来获得。例如,压缩1GB数据需要10s,或者系统具有100MBps的吞吐量,都可以用来表示速度。
效率
表示一个运行中的系统对外提供的能力与它本身需要的外部干预的比值,即效能比。通俗地讲,就是付出了多少成本,获得了多少收益。例如,程序需要在内存分配420字节的数据用于计算获取64字节的数据,就可以说这个过程对内存的利用效率约等于15%。
这里的15%并不是绝对意义上的效率值,因为我们并没有算上CPU时间、电力消耗、热量等其他外部资源。因此效率和我们的主观意识的边界有关,在我们的例子中就是内存空间。总而言之,性能至少是以上三要素的组合:
性能=(准确率×速度×效率)
优化三要素中的任何一个都可以提升应用程序的性能,提升诸如可靠性、可用性、弹性、整体延迟等。同样,忽视这些中的任何一项都会使我们的软件变得不那么有用(less useful)[4]。在性能优化的过程中,何时停止优化是关键,三要素表面上没有关联,实则相辅相成。例如,在保证准确率的情况下,是可以实现更好的可靠性和可用性的。又例如,为了提升程序性能,降低内存占用可以显著降低应用程序发生内存泄漏的概率。本书就侧重于研究这部分知识、技术与方法,探究如何在不降低准确率的情况下提升程序代码运行的速度与效率。
书名的由来
笔者的目标是传授最实用的技能,让读者能够较为轻松地编写出高质量、高性能的代码。为此,当笔者提到代码的整体性能时(未提及特定资源),指的是代码运行的速度和效率。
“性能”一词的误用只是软件效率这一主题的冰山一角,实际情况是,许多更加严重的误区正在加速摧毁软件的质量。从好的方面来看,这仅仅是一堆冗杂的巨量代码,但更糟糕的情况是,它会间接引起社会和财务组织管理问题。