近日,亚马逊官方博客上发布 “Sustainability with Rust” 一文,通过研究和对比来说明了 Rust 在可持续性方面优于其他语言。随后,ZDNet 也对此文进行了报道。在 ZDNet 的报道发出之后,Go 技术负责人 Russ Cox 连发 14 条推特,表示该文章在严重误导大家对 Go 语言的认知。
这件事引起了大家的关注,同时也引发了“Rust 还是 Go”的大讨论。那么,究竟发生了什么?
一篇文章引发的“对线”
在亚马逊,Rust 已经成为大规模构建基础设施的关键。2019 年,亚马逊成为 Rust 项目的赞助商。2020 年开始招聘 Rust 维护者和贡献者,并与谷歌、华为、微软和 Mozilla 联合成立了 Rust 基金会。
争议 1:几年前的研究有偏差
在发表的“Sustainability with Rust”文章中,为验证 Rust 是一种节能的编程语言,使用了 2017 年的一项研究数据进行证明。这项研究主要是对 27 种编程语⾔进行 10 个基准问题测试,并测量执行时间、能耗和峰值内存使用情况。以下为文章中引起争议的第一个部分:
几年前有一项非常有趣的研究,主要探索能源消耗、性能和内存使用之间的关系。这是关于可持续发展的常见话题。我们对服务的能源或碳使用的了解很少,是否有代理指标?是否可以查看现有基础设施成本、性能、内存等服务仪表板,并通过观察到的趋势来推测服务的能源消耗趋势?
该研究在 27 种不同的编程语言中进行了 10 个基准测试,并测量了执行时间、能耗和峰值内存使用的情况。C 和 Rust 在能效方面明显优于其他语言。事实上,它们的效率大约比 Java 高 50%,比 Python 高 98%。
C 和 Rust 比其他语言更高效就不足为奇了,但令人惊讶的是差异的幅度。保守估计,广泛采用 C 和 Rust 可以将计算能耗降低 50%。
那为什么大家不更多地使用 C?它的语言和开发工具都非常成熟,社区规模也比 Rust 大得多。在 2021 年的开源峰会上,Linux 创造者 Linus Torvalds 坦言,用 C 语言实现代码就像玩电锯。作为一名终身写 C 的程序员,Torvalds 知道,“(C 的微妙类型交互)并不总是合乎逻辑,对几乎所有人来说都是陷阱。”
Torvalds 称,Rust 是他见过的第一种可能解决问题的语言。Rust 提供了和 C 一样的能效,同时还没有未定义行为的风险。我们可以将能源消耗减半,同时不失去存储安全的好处。
多项分析结果显示,在 C/ C++中发生的高严重性 CVE 中,超过 70% 可以通过在 Rust 中实施相同的解决方案来预防。事实上,支持 Let's Encrypt 项目的非营利组织Internet Security Research Group (ISRG)(一个 2.6 亿个网站的证书颁发机构),目标是将所有互联网安全敏感的基础设施都迁移到内存安全的语言上,目前进行的项目包括在 Linux 内核中支持 Rust ,以及将 curl 迁移到 TLS 和 HTTP 的 Rust 实现。
我们再看看其他的研究结果。上图中间一列显示了执行时间的测试结果,Rust 和 C 的执行时间非常相似,这两种语言的执行速度都比其他语言要快。这意味着,选择 Rust 可以在获得可持续性和安全性优势的同时,还将拥有 C 的优化性能。
那么,文章里的这段论述出现了什么问题呢?Cox 指出,“几年前的有趣研究”是明显存在的问题。该研究于 2017 年 10 月在 Intel i5-4460 CPU(2014 年第二季度)上使用 Go 1.6(2016 年 2 月)进行。“那已经是永远的过去式了。”最重要的是,这个“真正有趣的研究”假设计算机语言基准游戏是个可比较的程序来源,但了解这个网站的话就知道这完全不正确。
Cox 表示,最明显的是,如果研究声称 C++ 的能源消耗比 C 使用多 34% 、执行时间快 56% 和内存多 14% ,那就需要重新检查这个研究的前提假设了。“几乎每个 C 程序都是有效的 C++ 程序,所以 C++ 不会输,尤其是没那么糟糕!”
“所以,这个‘真正有趣的研究’并不是真正的有趣。事实上,我们应该以辩证的怀疑态度来看待。”Cox 写道。
争议 2:不公平的对比
亚马逊工程师在文章中还以聊天软件 Discord 为例,讲述从 Go 切换到 Rust 的过程。Cox 认为,其引用的 Discord 内容里,关于从 Go 切换到 Rust 的部分存在令人难以置信的误导。以下为文章中引起争议的第二个部分:
Discord 最初以 Python、Go 和 Elixir 为主,但他们的一项关键 Go 服务存在问题。这是一个非常简单的服务,但还是导致其尾部延迟严重。这是因为 Go 是一种垃圾回收 (GC) 语言,所以在创建和释放对象时,垃圾回收器每隔一段时间就得停止程序的执行并运行一次垃圾回收。当 GC 运行时,进程无法响应请求,您可以看到 CPU 峰值和响应时间变化。
左:Go,右:Rust
为解决该问题,Discord 决定尝试用 Rust 重写服务,上图显示的就是使用结果。虽然 GC 峰值模式在 Rust 中消失了,但真正惊人的差异在于变化的幅度。注意, Go 和 Rust 的计量单位是不同的。
Rust 版本速度总体上快了 10 倍以上,甚至最差的尾部延迟减少了 100 倍。这些都是令人难以置信的改进,同时由于服务器响应效率变高,需要的服务器变少,这意味着使用的能源也更少。虽然 Discord 还没有决定开始用 Rust 来减少能源消耗,但这就是影响。
另外,Rust 并不是第一种高效的语言。C 已经存在了很长时间,但 Rust 是第一个在不牺牲安全性的情况下保证高效率的主流编程语言。用 C 和 C++ 编写的所有高危安全漏洞中,70% 是内存不安全造成的。Rust 提供了效率,但不会让人觉得自己在玩火。
对此,Cox 指出, Discord 的原帖中展示了一张 Go 服务器和等效 Rust 服务器的图表。Rust 具有更可预测的性能,并避免了像 Go 中的延迟峰值,但它们的性能大致相当。
Discord 原帖中的对比图,紫色线代表 Go,蓝色线代表 Rust
相反,在亚马逊的帖子里,在 Rust 和 Go 图表标出了“ms”与“µs”的时间刻度对比。但该对比的前提是,Rust 服务器进行了重大重写,并使用了新的数据结构和更多内存。
“这要么是完全没有理解 Discord 的帖子,要么就是公然说谎。”Cox 认为,这种对比方法在诚实、公平的情况下是很好的表达方式,“但 AWS 的帖子并非如此。”
不过,Cox 指出 Discord 的帖子是公平的。“它将 Go 服务器和 Rust 服务器进行了对比,并在文章后面单独绘制了 Rust 服务器在使用重写的数据结构和额外内存后的变化图,而 AWS 的帖子曲解了这一点。”
同时,Discord 的帖子也提到了 Go 1.10,而 Go 1.18 也将很快发布。这期间的 8 个版本有很多改进,减少了程序中有非常大的堆或非常多协议的 GC 暂停(Discord 服务器两者都有)。因此,使用最近的 Go 版本将显着减少 Discord 延迟峰值。“但 Rust 仍然是适合该服务器的优秀语言,团队作出了合理的决定。”
Cox 没有完全否认帖子里关于 Rust 的观点,但在 Cox 看来,亚马逊完全没必要加上关于 Go 的误导性陈述,“这看起来很丢人,Rust 足以独立存在。”
Go、Rust 之争
两种语言起源于同一时期。Go 于 2007 年构思并在 2009 年 11 月公开,Rust 出现在几个月后的 2010 年,尽管 Graydon 暗示 Rust 的构思可能要早得多。
Go 和 Rust 还有很多共同点。两者都是现代软件语言,旨在为影响软件开发的问题提供安全且可扩展的解决方案。两者还都是针对当时现有语言遇到的问题而创建,特别是开发人员在生产力、可扩展性、安全性和并发性方面遇到的问题。因此,两者常被认为是竞争关系。
但两者也有很多差异。谷歌 Go 编程语言的产品和战略负责人 Steve Francia 认为,Go 和 Rust 在性能并发、可扩展性、开源意识等方面有着相似之处,但两者有不同的权衡。Francia 在发布到thenewstack的文章里,详细比较了 Go 和 Rust 的差异。
在性能方面,Go 具有开箱即用的出色性能。按照设计,Go 中没有可以榨取更多性能的按钮或操纵杆。Rust 旨在让开发者能够从代码中榨取出每个性能,因此 Rust 有着更快的速度,代价是增加了复杂性。
在适应性方面,Go 快速迭代的优势使开发人员能够快速尝试想法,并在解决手头任务的工作代码上进行磨练。这通常就已经足够了,开发人员可以腾出时间做其他任务。另一方面,与 Go 相比,Rust 的编译时间更长,导致迭代时间更慢。这使得在更短周转期内,Go 允许开发人员能在不断变化的需求场景中工作得更好,Rust 则可以在拥有更多时间进行更精细、更高效开发的实现场景中发挥出色。
在易学性方面, Go 是更平易近人的语言,很多团队甚至能够在几周内使用 Go 并将 Go 服务/应用程序投入生产。而由于其复杂性,Rust 被认为是一种难以学习的语言,但这也为 Rust 带来了更高的性能。
在精确控制方面,Rust 拥有很大的优势。Rust 可以使开发人员在如何管理内存、如何使用机器的可用资源、如何优化代码以及如何制定解决方案等问题上,有更精准地控制。
因此,Francia 给出的建议是,Go 是大多数公司和开发者的正确默认选项,因为 Go 性能强大、易于采用,高度模块化特性使其特别适用于需求不断变化的情况。随着产品成熟和需求趋于稳定,企业可能有机会从边际性能的提升中获得巨大的收益。这些情况下,采用 Rust 来使性能最大化可能会是不错的选择。
结束语
“在我看来,与其阅读那些将 Go 与 Rust 视为零和游戏的文章,我更愿意关注那些将 Go 和 Rust 视为相互补充、能很好协同工作的文章。”Cox 在最后说道。
编程语言之争从来没有停过,每种语言都有大批的拥护者,甚至存在“鄙视链”的说法,每年的编程语言榜单也是大家竞相关注的热点。但编程语言之间并非水火不容,开发者需要学会选择适合自己的语言。
评论 1 条评论