本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。
基准测试
ruststream-gcp-pubsub 在每条消息上的开销:与裸 google-cloud-pubsub 客户端对照的吞吐量,以及它自身代码的指令数和内存分配次数。
与裸客户端对照
第一张图在本地 Pub/Sub 模拟器上用三种方式跑每个场景。「裸客户端」直接驱动 google-cloud-pubsub。
「Broker crate」只驱动这个 crate,不含其上的任何东西:它的订阅、它交出的投递、它的发布者,由一个外面
没有服务的循环来读取和确认。「RustStream」是用户会写的服务:#[subscriber] 处理器、应用和运行时。
第一段差距是这个 crate 在它所封装的客户端之上的开销,这个数字由本仓库负责;第二段是运行时叠在上面的
开销,而且是在 Pub/Sub 上的那一份。
每个循环画成一条从最佳一轮到最慢一轮的横条,圆点标出最佳一轮,刻痕标出中位一轮。坐标轴的零点是裸客户端 的最佳一轮,圆点在零点右侧表示更慢。空心圆点表示该循环与裸客户端的差值小于各轮的波动范围。图下的表格 给出最佳一轮,括号里是中位一轮。
第二个场景带着排序键发布,这正是开启了排序的订阅必须按键保序的那种投递形态。它同时给这个 crate 多加了第一个场景没有的一份活:键被搬进投递的头里,不指名 Broker 的服务就从那里把它当作分区键读 出来。客户端上的循环读消息上的字段,什么也不复制。
代码的开销
第二张图数一条消息在服务线程上花掉多少:指令数由 callgrind 统计,内存分配次数由 DHAT 统计,都是稳态下
的值。每个场景都是用户会写的那种服务:它建在 PubSubBroker 上,对着同一套环境里的模拟器启动。服务线程
上的一切都计入:框架的分发、本 crate 的代码,以及 google-cloud-pubsub 客户端,它的流式拉取、确认、
确认截止时间的延长和发布请求都在这里运行。「冷启动」是启动服务并处理第一次投递一次性付出的开销。
每一行的大头都是客户端。回复那一行最重:运行时要等每条回复得到确认,才去取下一次投递,所以每条回复 都单独作为一个发布请求发出。冷启动的开销也几乎全在客户端:它要构建两个管理客户端,每一个都会读取并 解析这台机器的根证书,所以这一列取决于机器上的证书库。
结果
- 裸客户端
- Broker crate
- RustStream
- 各轮,从最佳到最慢
- 最佳一轮
- 中位一轮
- 轮次的波动范围
- 无法区分
ruststream-gcp-pubsub 0.7.0 on ruststream 0.7.0, AMD Ryzen 9 7900X 12-Core Processor, Linux 7.2.10-x64v3-xanmod1-1, Pub/Sub emulator, gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators, Google Cloud SDK 587.0.0, in Docker on localhost, 测量于 2026-10-18. 这些数字是怎样测得的
- 无法区分
- 无法区分
- 无法区分
- 无法区分 (受 Broker 限制)
以表格显示数字
| 场景 | 裸客户端 | Broker crate | RustStream | 额外开销 |
|---|---|---|---|---|
| Streaming pull, 512 B JSON, ack each | 1,815 msg/s (1,807) | 1,805 msg/s (1,803) (比客户端 无法区分) | 1,819 msg/s (1,809) | 无法区分 |
| Streaming pull with ordering keys, 512 B JSON, ack each | 1,987 msg/s (1,986) | 1,987 msg/s (1,986) (比客户端 无法区分) | 1,988 msg/s (1,988) | 无法区分 (受 Broker 限制) |
AMD Ryzen 9 7900X 12-Core Processor, x86_64, 427-5912 MHz, 12 physical, 24 logical, 62.4 GiB, unknown, Linux 7.2.10-x64v3-xanmod1-1, 1.99.0, 3.25.1, bench, inheriting release (opt-level = 3, lto = fat, codegen-units = 16, debug = line-tables-only), ruststream-gcp-pubsub default (none), ruststream macros,json; google-cloud-pubsub 1.3.0. ruststream-gcp-pubsub 0.7.0, ruststream 0.7.0, 测量于 2026-10-18.
以表格显示数字
| 场景 | 指令数 | 内存分配 | 冷启动 |
|---|---|---|---|
| consume, JSON decode into a small struct, ack each | 10,571 | 5.4 | 87,632,378 / 7,653 |
| reply to a declared topic, each confirmed before the next delivery | 106,926.5 | 88.3 | 87,639,206 / 7,680 |
| consume in batches of 64, assembled on the client | 10,809.5 | 5.5 | 87,640,196 / 7,657 |
机器
| 处理器 | AMD Ryzen 9 7900X 12-Core Processor |
|---|---|
| 架构 | x86_64 |
| 频率 | 427-5912 MHz |
| 核心数 | 12 physical, 24 logical |
| 内存 | 62.4 GiB |
| 内存速度 | unknown |
| 操作系统 | Linux 7.2.10-x64v3-xanmod1-1 |
| Broker | Pub/Sub emulator, gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators, Google Cloud SDK 587.0.0, in Docker on localhost |
| 往返时间 | 0.269 ms (20000 GetSubscription calls on one connection); a delivery is charged 1 of them |
| 编译器 | 1.99.0 |
| 构建配置 | bench, inheriting release (opt-level = 3, lto = fat, codegen-units = 16, debug = line-tables-only) |
| 特性 | ruststream-gcp-pubsub default (none), ruststream macros,json; google-cloud-pubsub 1.3.0 |
| RUSTFLAGS | none (the recipe clears RUSTFLAGS, so the numbers are not tied to this CPU) |
| Valgrind | 3.25.1 |
构建标志和数字一起公布,因为它们会改变这些数字。用 -C target-cpu=native 构建出的二进制给出的
结果,换一台机器就复现不了,所以这条 recipe 在构建前先把这个变量清空。
这些数字来自这个版本的 docs/benchmarks/results.json,由基准测试 recipe 写入。同一份文档公布在
benchmarks/results.json,
框架的站点用它拼出跨 Broker 的汇总表。方法论说明这些数字怎样测得,
数字说明它们能支持哪些结论。