性能比拼: Rust vs Zig vs Go

本内容是对知名性能评测博主 Anton Putra Rust vs Zig vs Go: Performance (Latency - Throughput - Saturation - Availability) 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准

在本视频中,我们将对 Rust、Zig 和 Golang 进行比较。我使用 Actix HTTP 框架 运行 Rust,标准库 运行 Golang,并使用 较新的 Zek 框架 运行 Zig。

我之所以更新这个基准测试,是因为我收到了一位 熟悉 Zig 的开发者 提交的 Pull Request,因此我决定重新进行一次测试。

在本次测试中,我们将重点关注 四个关键指标:

  1. 延迟(Latency) :使用 P99 百分位 进行测量。
  2. 吞吐量(Throughput) :即 每秒可以处理的请求数,用于衡量不同 HTTP 框架的性能。
  3. 资源使用情况(Saturation) :包括 CPU 使用率(相对于 Kubernetes 定义的限额) 和 内存使用情况 。在本测试中,我们直接使用 实际的内存使用值 。此外,由于测试是在 Kubernetes 中运行的,我们还需要测量 CPU 限制(Throttling)。
  4. 错误率或可用性(Errors/Availability) :对于 HTTP 服务来说,这指的是 成功请求数与总请求数的比率。

我使用了 生产级 Kubernetes 集群 在 AWS 上运行大部分基准测试,以确保测试环境尽可能接近 真实的生产环境 。应用程序部署在 大型 EC2 实例 上,客户端运行在 四核 Graviton 实例(基于 ARM 架构,成本略低于 AMD)。


测试方法

在本次测试中,我创建了一个 API 端点 (/api/api/devices),客户端会向该端点发送请求,并获取一个 硬编码的设备信息 。这个测试虽然非常简单,但可以很好地反映 每个应用程序的基准性能。

测试开始

首先,我运行 三个应用程序 5 分钟 ,并 不施加任何负载。

  • 这次测试中,我决定 直接显示实际的内存使用量(单位:字节)。
  • Rust 在空闲状态下仅占用不到 1MB 内存 ,而 Zig 约占 25MB。

接下来,我 部署客户端 并施加负载。整个测试持续 大约 2 小时 ,但我已将其 压缩为几分钟 展示结果。


测试结果

CPU 和延迟
  • Golang 从一开始 CPU 使用率就较高 ,并且其 延迟比 Rust 和 Zig 略高。
  • Rust 和 Zig 在几乎所有指标上都非常接近 ,除了 内存使用量。但这种情况很快会发生变化。
吞吐量
  • 当请求数达到 20,000 QPS(每秒请求数)时 ,Golang 开始 性能下降,延迟上升。
  • 我已应用了所有推荐的优化技术,相关 源代码可在我的仓库中查看。
  • 当 QPS 达到 33,000 时,Golang 的延迟问题变得更加明显,已经无法与 Rust 和 Zig 竞争 ,因此从这里开始,我的重点将放在 Rust 和 Zig 的对比 上。
可用性(Availability)
  • 当 QPS 达到 40,000 时,Rust 的 可用性曲线出现小幅下降。
  • 由于 平均请求处理时间低于 1ms ,我将 超时时间设定为 100ms。
  • 当客户端 请求超时 ,它会收到 HTTP 408 错误码 ,导致 可用性下降。
资源使用情况
  • 当 QPS 达到 51,000 时,Golang 开始 丢失部分请求,无法继续保持较高的吞吐量。
  • Golang 的缓存使用量不断增加 ,最终超出 Kubernetes 设定的 256MB 内存限制 ,导致 进程被 OOM(内存溢出)终止。
Rust vs Zig
  • Rust 的内存使用量最终达到了 Zig 的水平,并在高负载下超过了 Zig。

  • 当 QPS 达到 98,000 时,Rust 开始 性能下降:

    • RPS(每秒请求数)下降,无法维持原有吞吐量。
    • 延迟上升。
    • Rust 开始返回错误,导致可用性下降(由于大量超时请求)。
  • 在 RPS 计算时,我仅统计成功请求 ,因此 Rust 的请求总数出现了 略微下降。

总体吞吐量
  • 最终,Kubernetes 开始限制 Golang 的 CPU 资源 ,但此时它的性能 已经无法与 Rust 和 Zig 竞争。
  • Zig 的最大吞吐量约为 118,000 QPS ,Rust 为 113,000 QPS ,而 Golang 仅能达到 70,000 QPS。

数据可视化

接下来,我展示了完整测试时长内的各项数据指标的变化情况:

  1. 每秒请求数(RPS)
  • Golang 远低于 Rust 和 Zig ,处理能力约 70,000 QPS。
  • Rust 和 Zig 均可达到 100,000 QPS 以上。
  1. 延迟(Latency)
  • Rust 和 Zig 之间的延迟差距很小。
  • Golang 的延迟明显更高。
  1. CPU 使用率(CPU Usage)
  • Golang 从一开始就消耗更多 CPU 资源。
  • Rust 和 Zig 的 CPU 使用率更稳定。
  1. 内存使用量(Memory Usage)
  • Golang 多次被 OOM 终止 ,导致 多个进程被杀死并重启。
  • Rust 和 Zig 的内存使用量相对稳定。
  1. 可用性(Availability)
  • Rust 在高负载下出现了部分超时错误,导致可用性下降。
  • Zig 的可用性相对较高。
  1. CPU 限制(CPU Throttling)

(图略)

  • Golang 在测试后期受到了 Kubernetes 的 CPU 限制,但此时它的性能已经下降,影响不大。
相关推荐
hhhjhl10 小时前
Undici 跨端三方库仓颉适配全流程
java·开发语言·ubuntu
染指111010 小时前
158.Agent-LangGraph-子图(共享状态和不共享状态模式)
开发语言·人工智能·python·ui·agent·agents
wangchunyu11411 小时前
JAVA JVM内存结构与运行时数据区
java·开发语言·jvm
slongzhang_11 小时前
linux 递归删除源码文件|递归删除目录下 *.js,但排除 *.min.js
linux·开发语言·javascript
云和数据.ChenGuang12 小时前
Python 常见特殊方法详解:__new__、__init__、__del__、__str__、__repr__ 与 __getattribute__
开发语言·人工智能·python·1024程序员节
xyouyuweizhu12 小时前
字节流与字符流:Java IO 的两条主线该怎么选
java·开发语言·python
多弗朗皮卡丘13 小时前
C++的IO流
开发语言·c++·io流·文件io流
骑着蜗牛撵大象32713 小时前
AI Agent 工程化开发实战(三):用 StateGraph 给智能体搭一条可回放的状态流水线
java·开发语言·jvm·ai·状态管理·langgraph·stategraph
itmigrate13 小时前
Rust 里的所有权误区:不是不写 clone 就叫高性能
开发语言·后端·rust
Brilliantwxx14 小时前
【Linux】 文件访问与路径解析:目录、文件名、dentry、路径缓冲与 dcache 全解析
linux·运维·服务器·开发语言·spring