语言的性能不重要

198 阅读5分钟

语言性能并不重要

最近一个备受争议的话题是Rust是否比c++快,它取代了之前关于c++是否比C快的讨论,有时甚至提到了Java。

显而易见: 一段特定的代码能跑多快取决于微基准测试程序, 这也正是我们所关注的. 执行一小段独立代码的完美优化版本需要多少CPU周期?

但一旦我们稍微放宽眼界,需要意识到我们所做的假设。例如,我们能否提供数据给我们的微优化代码片段,使其能够以接近全速的速度运行,或者周围的代码会减慢它的速度?即使我们只对延迟(或µW)感兴趣而非吞吐量, 我们也很可能在多线程、多进程甚至多虚拟机环境中,而这些环境可能完全支配我们的延迟。

微基准测试程序的最后一环是编译器质量和虚拟机。在微观层面对编译语言和大多数即时编译过语言进行比较,唯一的区别是强制对代码进行额外检查。例如,边界检查(数组、整数)将导致运行时增加,但没有这些检查的代码不是等效代码。因此,在JavaScript里有许多的例子,代码会被即时编译成最优的二进制代码,就像c++会生成的代码一样。

一种全新有效查看性能更好的方法是制定面向用户的服务级别目标。只要达到这些目标,我们就可以安全地声明"代码足够快"。

换句话说,如果你写了完美可读的高级代码,这段代码会有多快。此外,您需要自己编写多少性能关键代码?你也可以将其视为将你的全部工作分解为 “初始编码”“优化”

在这种情况下,我们开始看到差异化。脚本语言突然引入了一个障碍。快速代码必须包含在预编译模块中,并且通常用C语言编写。

然而,脚本语言并不是唯一引入障碍的语言。以下是一些无法完全优化且引起运行时延长的其他特性:

  • 函数式语言中的不可变数据
  • 安全特性需要运行时检查
  • 自动化的内存管理

可用工具的质量对于轻松地编写快速代码也有很大的影响。例如,对于编译语言,PGO通常会导致20%的性能提升。

但我们也不要忘记等式的另外一端。我们可以思考我们使用的代码(语言)有多快,但我们写代码有多快呢?

机会成本

在商业中,一切都是金钱,但要计算工程师的机会成本可能并不容易,这是你应该考虑的事情。你的生产效率越高,基准成本(你为留住该员工付出了多少成本)和机会成本(该员工提供了多少价值)之间的差异就越大。

这使得讨论我们编写快速代码的速度变得非常困难,因为它变成了一个动态问题。决定优化的两个主要原因:

  • 通过减少资源占用所节省的X天机会成本是值得的。
  • 该产品没有达到阻止它产生新特性的的SLA(服务等级协议)。

这意味着您很容易陷入这样一种情况:用脚本语言编写所有代码不会触发上述任何一种情况。如果产品迅速迭代,节省资源的机会就不太容易出现。无法满足SLA(服务等级协议)的问题,可以通过增加资源占用来更容易、更便宜地解决。

在微观层面上,识别糟糕的性能模式已经成为基本编程能力一部分。例如,通过LeetCode等网站,软件工程师已经被灌输了知道什么时候使用哈希映射或二分搜索的知识,这已经成为找工作的必要条件。

意识到同样的模式在架构中更有挑战性:

  • 高水平噪音使得论证性能更加困难。
  • 责任划分自然会导致效率低下,但这可能是必要的。
  • 了解第三方组件的详细的性能特性是个挑战。

但与此同时,架构将胜过任何微观层面的性能改进。例如,假设您要多次处理输入数据,并且可以提高处理速度或只处理一次输入。在这种情况下,你谈论的5-10%的加速比是从微优化,但可能80%甚至更高的加速来自删除重复的工作。

如果您部署在线软件并需要动态缩放,那么所有这些都会变得成倍地复杂。

您的代码库中有一些可以并且应该优化到极限的组件。例如,解析和验证输入,核心数字功能(如加密和哈希),任何特定领域的计算繁重的代码(AI,图像...)。但这些都是你自己写的,还是把这些令人头疼的东西丢给一个软件库去处理?

更重要的是,与其他代码相比,您花费了多少比例的时间在编码实现? 在我的项目中,编码部分只占总时间的0.5%-10%。所以在元层面上,编码的效率是我最不担心的。

此外,从公司的角度来看,尤其是如果你的公司规模很小,那么轻松地寻找特定语言人才的能力应该比其他任何考虑因素都重要。

除非你在做低延迟的交易,在这种情况下,什么都不重要,因为保存一个CPU周期就能转化成数目惊人的钱。

感谢阅读这篇文章。希望你喜欢

我也在 YouTube发布视频. 如有问题请联系我 Twitter 或者 LinkedIn.