[译]软件性能仍然重要吗?

本文由Daniel Lemire发表于2017/03/20, 原文链接在此

今天早上,一位读者请教我关于现实世界里软件性能的话题:

我对你利用计算机架构相关技术来优化算法性能的工作很感兴趣。然而,我觉得这种东西只有学术界比较感兴趣。你觉得这种特殊的领域有什么就业机会吗?

用这位读者的话来说,计算机和软件已经够快了。我们可能更需要人们去实现新的创意,而性能并不重要。更有甚者说,如果想要得到高酬劳的工作,就不需要关心软件性能。

要评价这个问题,我们首先必须就“软件性能到底是什么?”达成共识。软件性能并不是说你能够多快地处理一堆数字。应该是你如何管理内存、磁盘、网络和CPU等…这还关系到整个架构。也并不是要求用机器码去重写你的代码: 你可以用 JavaScript 去写快速应用部分,用 C++ 去写运行慢速的那部分。软件性能和设计算法有关,但是又有一点很重要的区别:你必须把你的架构考虑在内。很多算法在理论上看上去很优秀,但是实际运行起来性能很渣。而那些看上去很傻很天真的算法有时候却是性能的最佳选择。某种层面上来说,掌握软件性能实际上要求你对计算机硬件、操作系统和运行时库如何工作有非常深刻的理解,

So, 都7102年了,我们还要care软件性能么?

我的简单回答是这样。我们评价一个程序员的两个基本点是:你写的代码是否正确运行?你写的代码是否高效?当然程序员还有其它的方式贡献价值:比如说利用某些业务领域的经验创造价值或者设计出惊艳的UI界面。然而,在硬核编程部分,准确和高效是两个主要的因素。

看看伟大的程序员是怎样的。他们很擅长编写即正确又高效的软件。实际上这就是一个伟大程序员的定义。当你同时做到准确和高效时编程才是一件有挑战性的事情。如果允许你去牺牲任何一个,那你可以去解决许多的任务了。

在招聘的描述里,你可能不会看到太多对程序员高效编码的要求,同样也不会看到太多要程序员编写正确运行代码的要求。但是于此同时,你也不会看到医生的招聘要求写着能治愈患者,律师的招聘要求写着能给避免昂贵的诉讼费。从系统架构的角度去编写高效的代码是一名程序员的基本工作要求。

我一些更详细的思考:

  • 关乎软件性能的只有那一小部分代码。更在乎的是它的绝对价值,而非相对代码数量。

    如果你只有很少的用户和数据,那软件性能无足轻重。越重要的软件,性能问题也变得更重要。

    鉴于我们编写的软件中有90%实际上都很少在工作,大部分情况下我们可以去赌软件性能不重要,但这也只是大部分情况下… 在这些场景下软件带来的价值很少。

    让我们讲得更准确一些:绝大多数性能或内存优化是无用功。

    这不是什么虚构,这是事实。

    一大堆的软件生来就不是追求性能或者不值得为性能而付出的。帕累托法则告诉你20%的代码消耗80%的运行时间,但是我认为比这个还糟。我认为1%的代码占用了99%的运行时间……事实可能更极端。

    所以只有一小部分代码才关乎性能,而且其中的更一小部分才带来商业价值。

    但重要的是,如果你是员工,你的价值取决于你对优化业务代码所带来的价值,而不是以你接触到的代码多少来衡量。

  • 我们可以量化软件性能的价值,而且非常具有价值。

    如果我去苹果的官网购买一台MacBook Pro。基础款$1800。如果我想要一个CPU主频高10%的型号,将花费$2100(加价+15%)。仅仅10%的主频速度提升并不能完全接近10%的速度提升。我们只能说大概会快5%。因此为了让计算机快5%(如果有的话)有些人更愿意付出多15%甚至更高的价格。对手机来说完全也可以同样这么分析。

    如果说与性能相关的常量因素不重要的话,那么让计算机实现两倍速的提升应该有同等价值的体现。实际上就是说,如果一台计算机能够以两倍速运行,那么它的价格同样也应该值两倍。

    就云计算来说,现在公司经常以他们使用的资源(内存、计算时间)来付费。这就允许他们很方便地衡量(美元)给定优化带来的收益。我们可以看到小公司如何利用初级优化手段节省数百甚至数千美元

    我们也可以看看浏览器。长久以来,微软一直以IE浏览器领先。在很多关键市场,谷歌Chrome浏览器现在已经主宰了。人们选择谷歌Chrome浏览器有很多原因,但是速度是一个关键因素。为了验证我的理论,我在谷歌上搜了下:帮我选择Chrome还是IE,我看到的第一个推荐是下面这个:

    Chrome是理论上速度最快的浏览器,最关键的功能是它更够快速地加载网页。我们用Sunspider、Octave和HTML 5测试对Chrome和IE浏览器做了一系列的性能测试。在每一项指标中,谷歌Chrome都遥遥领先。

    因此,性能对很多用户来说是有价值的。

  • 添加更多的硬件并不会神奇般地让性能问题消失。它需要用工程方法去利用更多的硬件。

    有人反对说,慢的时候我们总是可以堆叠更多的机器、核数。然而即使阿姆达尔定律不限制你,你仍然要面对无法让你的软件在多台机器上良好运行的事实。堆叠硬件只是提升软件性能的一个特殊方法。它未必是个廉价的方法。

    可以说现实世界里没人能够拥有无穷多的处理器。此外,当你有多个处理器时,协同问题会让你在多个处理器上处理同一个问题上更加复杂(即使在理论上也是如此)。

    我们又是如何实践的呢?过去的几十年告诉我们并行处理问题是件困难的任务。你最终会遇到更加复杂的代码和高昂的开销。测试和调试变得更加困难。当面临许多问题的时候,你如果能够用三个核数换取两倍的性能提升,那已经很幸运了。接着如果你想再让性能翻倍,估计你得需要16核CPU了。

    这意味着如果单线程性能提升两倍,将会变得非常有价值。换句话说,调优热点代码的意义更大…… 而且添加更多的硬件并不会让性能问题神奇般地消失,使用这些硬件需要额外的处理工作。

  • 我们使用高级编程语言,但是在弥补性能缺失上投入了大量的工程精力。

    当今最流行的编程语言是JavaScript,一个相对比较慢的编程语言。这难道标志着性能不重要?在过去几年里JavaScript的性能成倍提升背后是大量的工程投入。此外,我们正在推动一些高性能的网络编程技术,例如Web Assembly(参见这个视频)。如果性能不重要,这些将变得没有意义。

    事实上,随着时间推移,人们迁移到更加高级的语言。这是件好事。这些语言通常以牺牲性能来换取便利性、安全性或简易性。

    虽然在过去的十五年里,浏览器中的JavaScript性能提高了两个数量级。但是,在一些评估中JavaScript只有C++的十分之一性能。

    我认为JavaScript流行的一个重要原因正是其良好的性能。如果JavaScript在大多数任务中仍然比C++慢1000倍,那么它就不可能像现在这样的流行。

    去年,一个同事遇到一个仿真的性能问题,程序一直在无尽地运行。当我问她是用什么编程语言时,她惭愧地说是用Python写的。也许令她惊讶的是,我没有表示出任何不屑。在20年后,如果我们大多数人仍然用C,C++和Java编程,那我才会沮丧。

    你值得为更好的性能和更高效的生产力买单。

  • 计算机被要求用更少的资源做更多的事情,而且在性能方面永远有着无尽的需求。

    软件性能经常被认为是无关紧要的。根据摩尔定律,这是完全可以理解的:处理器更快,磁盘更快…… 谁在乎软件慢不慢?它迟早会运行得更快的。让我们专注地用漂亮的算法编写漂亮的代码,剩下的都可以无视。

    的确如此,如果你在一台最近购买的PC机上运行Windows 3.1,它会快得不可思议。事实上,我敢打赌,你可以在你浏览器里运行Windows 3.1,让它更快。

    的确有些硬件在生成高效的代码上的压力越来越小。在1990年,为了击败最强的国际象棋棋手,可能甚至需要有人专门去调优汇编代码。而如今我敢保证我随便用JavaScript写一些邋遢的代码就能够写出一个足以击败大多数非大师级国际象棋棋手的软件。

    但是计算机被要求使用更少的资源。在1990年写一个国际象棋程序击败国际象棋冠军非常的了不起…但在今天来看简单得根本算不上什么伟大的事情。你需要去写一个下围棋的程序,那个才是件难事。

    当然了,手机硬件速度总是越来越快…… 但是想在体积更小、更廉价的设备上运行同一款软件压力就大了(例如智能手表)。十几年后鼠标和键盘变成了奇怪的古董,取而代之的是更昂贵的交互(如语音、增强现实……)。

    是的,很快我们就需要一个像智能手表一样大小的具备自主高级自主人工智能的设备。你觉得你那草率未经优化的代码能够跑在上面?

  • 我们确实希望我们的处理器大部分的时间是空闲状态。事实上并不是说我们的代码可以更松散(可能翻译不准确,原文:The fact that they are is not an indication that we could be sloppier)。

    我们的处理器大多时候是空闲状态吗?

    是的,但是这就像那个梗:买一辆跑车,而它大部分的时间都是停在那里,多蠢。

    我们有巨大的过剩算力,设计就是如此。否则那场景就会像超市里所有收银台、所有购物车全天都满负荷运作。

    我们都经历过笔记本电脑CPU使用率为100%的情况。笔记本电脑变得迟钝,没有反应。你的所有操作请求都要排队等候。这很不爽。

    服务器满负荷运行的情况下不得不丢弃请求或者让你等待。我们讨厌这种情况。

    一部满负荷运行的手机变烫,然后很快地耗尽它的电池。

    所以我们希望我们的处理器是冷却的,并且保持这种冷却状态。有效的方法是减少它们的使用,即使他们大部分时间是冷却。快速的代码可以更快地返回给用户并消耗更少的能量。

    我想未来将是由暗硅制成的。我们将拥有大量的算力、大量的电路,但大多数都处于无功耗的。如果我们很快就会根据软件使用的功耗来评估它,那我一点不会感到惊讶。