本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。
基准测试
ruststream-sea-file 在每条消息上的开销:与裸 sea-streamer-file 客户端对照的吞吐量,以及它自身代码的指令数和内存分配次数。
与裸客户端对照
第一张图在本机磁盘上的一个流文件上,把两个场景各用三种方式运行。裸客户端 直接驱动 sea-streamer-file 的 streamer、消费者和生产者。Broker crate 用一个自己的循环驱动本 crate 的订阅和发布者,上面没有运行时。RustStream 是用户写的服务:应用里的一个 #[subscriber] 处理器。第一项差值是本 crate 比它所封装的客户端多付出的开销,第二项是运行时在其上增加的开销。
每个循环画成一条横条,从最佳一轮延伸到最慢的一轮,圆点标出最佳一轮,缺口标出中位一轮。坐标轴的零点是裸客户端的最佳一轮:圆点在零点右侧表示更慢,在左侧表示更快。空心圆点表示该循环与裸客户端的差异小于各轮的波动范围。图表下方的表格列出最佳一轮,括号里是中位数。
两个场景对应读取流文件的两种方式。重放读取一个在订阅打开之前就已完整写好的文件,没有任何东西限制它的节奏。实时跟随读取一个仍在追加的文件,每次投递都要等待一次追加。
在重放这一行,RustStream 比裸客户端快,本 crate 自己的循环与裸客户端持平。本 crate 的订阅在单独的任务上预读,因此在处理当前消息的同时,下一条消息已经从文件中读出。手写的裸循环在同一个任务里读取和处理。
代码的开销
第二张图统计一条消息在服务线程上的开销:稳态下 callgrind 测得的指令数和 DHAT 测得的内存分配次数。每个场景都是一个基于 FileBroker、使用自己的流文件的服务。计数包括框架的分发、本 crate 的代码,以及在该线程上运行的那部分客户端代码。客户端的写入者,以及在 tokio 阻塞线程上进行的文件读写,不计入。冷启动 是启动服务并取得第一条消息一次性付出的开销。
结果
- 裸客户端
- Broker crate
- RustStream
- 各轮,从最佳到最慢
- 最佳一轮
- 中位一轮
- 轮次的波动范围
- 无法区分
ruststream-sea-file 0.7.0 on ruststream 0.7.0, AMD Ryzen 9 7900X 12-Core Processor, Linux 7.2.11-x64v3-xanmod1-1, none: the transport is a stream file on this machine's filesystem, 测量于 2026-10-18. 这些数字是怎样测得的
- 无法区分
- -41.4%
- 无法区分
- +3.3% (受存储限制)
以表格显示数字
| 场景 | 裸客户端 | Broker crate | RustStream | 额外开销 |
|---|---|---|---|---|
| replay of a recorded stream file, 512 B JSON | 226,428 msg/s (206,683) | 227,695 msg/s (225,547) (比客户端 无法区分) | 320,151 msg/s (313,104) | -41.4% |
| live tail of a file being appended to, 512 B JSON | 68,880 msg/s (68,702) | 68,090 msg/s (67,417) (比客户端 无法区分) | 66,630 msg/s (65,933) | +3.3% (受存储限制) |
AMD Ryzen 9 7900X 12-Core Processor, x86_64, 427-5912 MHz, 12 physical, 24 logical, 62.4 GiB, unknown, Linux 7.2.11-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-sea-file default (none), ruststream macros,json. ruststream-sea-file 0.7.0, ruststream 0.7.0, 测量于 2026-10-18.
以表格显示数字
| 场景 | 指令数 | 内存分配 | 冷启动 |
|---|---|---|---|
| consume, JSON decode into a small struct | 52,957 | 32.5 | 194,100 / 236 |
| reply, appended to the same file by this crate's publisher | 81,033.3 | 73.3 | 196,968 / 245 |
| consume in batches of 64, assembled on the client | 52,971.1 | 32.5 | 221,502 / 247 |
机器
| 处理器 | AMD Ryzen 9 7900X 12-Core Processor |
|---|---|
| 架构 | x86_64 |
| 频率 | 427-5912 MHz |
| 核心数 | 12 physical, 24 logical |
| 内存 | 62.4 GiB |
| 内存速度 | unknown |
| 操作系统 | Linux 7.2.11-x64v3-xanmod1-1 |
| Broker | none: the transport is a stream file on this machine's filesystem |
| 文件系统 | btrfs on /dev/nvme2n1p1 |
| 流文件大小 | 0.71 GiB per run at its largest |
| 页缓存 | warm: every run writes its stream file immediately before reading it back, so the figures are the filesystem's rather than the device's |
| 一次追加 | 18.0 us per flushed append |
| 编译器 | 1.99.0 |
| 构建配置 | bench, inheriting release (opt-level = 3, lto = fat, codegen-units = 16, debug = line-tables-only) |
| 特性 | ruststream-sea-file default (none), ruststream macros,json |
| RUSTFLAGS | none (the recipe clears RUSTFLAGS, so the numbers are not tied to this CPU) |
| Valgrind | 3.25.1 |
传输是一个文件,因此文件系统取代了 Broker 的服务器,这些数字既属于本 crate,也同样属于文件系统。一次追加 是单独测得的一次追加并刷写到文件的时间。
数字来自本版本的 docs/benchmarks/results.json,由基准测试命令写入。方法论说明它们是怎样测得的,数字说明可以从中得出什么结论。