This Week in Rust 651 - 深度总结

This Week in Rust 651 - 深度总结

This Week in Rust 651 - 深度总结

原文发布于 2026年5月13日 | 本期共合并502个PR | 原文链接


目录

  1. 社区更新
  2. 本期精选文章
  3. Rust 项目更新
  4. 本期 Crate
  5. RFC 动态
  6. 即将到来的活动
  7. 本周金句

社区更新

Rust 基金会:开源可持续性危机联合行动

Rust 基金会宣布作为创始成员加入 Linux 基金会旗下的 “Sustaining Package Registries Working Group”(可持续包注册表工作组)。2025年全球包下载量逼近 10万亿次,AI驱动的需求、机器人流量、自动化发布和安全事件急剧增长,暴露了包注册表可持续性的巨大缺口。

工作组核心目标包括:

  • 经济可持续性:开发可被注册表采用的资金模型
  • 集体防御:跨注册表协调安全实践与信息共享
  • 治理赋能:制定共享政策框架与标准化条款
  • 生态教育:提升社区对注册表可持续性努力的理解

Rust 基金会执行董事 Dr. Rebecca Rumbul 表示:”Rust 被设计用来让软件更安全、更可靠,但这一承诺依赖 crates.io 保持可信和资源充足。”


本期精选文章

1. 杀死一只 Cow——我的 JSON 格式化器提速42%

作者:Jacob Asper | 原文

这是一篇精彩的性能优化实战,作者通过消除 Cow<str> 的开销,将一个 JSON 格式化器提速了42%。

核心发现

  • Cow<str> 的隐藏成本:即使 Cow::Borrowed 不分配内存,它的 Drop 检查仍占程序指令的20%。每个 Token 变体都需要执行清理分支——即使它不持有数据。
  • 状态机拆分:将数字解析状态机拆成 MantissaStateExponentState,让 CPU 一次缓存读取就能获取完整状态(从88字节缩减到适合64字节缓存行)。

迭代过程

迭代 方案 strings+deep nesting 吞吐量 变化
基线 单个 Cow<str> 229.5 MB/s -
迭代1 2个 Cow<str> (mantissa + exponent) ~214 MB/s -6.7%
迭代2 改为 &str ~341 MB/s +32%
迭代3 拆分 Mantissa/Exponent 变体 ~357 MB/s +4.5%
最终 拆分状态机 325.5 MB/s +42%

关键启示

  • CPU 缓存行是64字节——token 大小小于32字节时,CPU一次读取可处理2个 token
  • 大多数场景下(混合数据类型),性能提升显著(many objects +18.5%,deep nesting +49.4%)
  • 唯一的性能回退是纯浮点数数据集(-3.7%),在典型混合数据场景下是可接受的权衡

2. mpsc 通道的隐藏内存成本

作者:howardjohn | 原文

作者在优化其 Rust 反向代理 agentgateway 内存使用时,发现 Tokio mpsc 通道的惊人内存开销。

核心发现

  • Tokio 的 mpsc::channel::<T>(N)初始分配与 capacity 参数 N 无关
  • 实际初始分配 = (sizeof(T) * 32) + 544 字节
  • 根源:Tokio 内部以 Block 为单位管理通道,每个 Block 硬编码存放 32 个元素

实际数据

消息大小 capacity 创建后堆分配
8 B 1 800 B
128 B 1 4,640 B
1024 B 1 33,312 B
1024 B 1024 33,312 B (初始相同)

真实世界影响

  1. 数千个小型通道(每条消息24字节):每个通道占1,312字节。切换到 futures-channel(每次只分配一个 T)后,整体内存减半。
  2. Hyper 连接(每个请求约250字节):每个 HTTP 连接额外浪费 8KB(250×32),Hyper 已在 Issue #4057 追踪此问题。

3. 构建高性能 Rust Profiler 的经验教训

作者:Paweł Urbanek | 原文

hotpath-rs 作者分享了过去6个月构建该 profiler 的深度技术细节(已超过 10 万下载)。

核心设计理念

不同的性能信号讲述不同的故事。hotpath 将三种信号合并到一份报告中:

  • Timing(挂钟时间):显示异步 I/O 等待,CPU profiler 无法捕获
  • Alloc(内存分配):细粒度归因每个函数的分配字节数
  • CPU(CPU采样):集成 samply,显示 CPU 真正”烧”在哪里

关键技术挑战与解决方案

1. MPSC 通道瓶颈

  • 问题:即使每微秒发送一次数据,crossbeam-channelselect! 宏也会让接收线程进入 parked 状态,导致 Thread::unpark 占 CPU 时间22%
  • 解决:每个线程批量发送测量数据,将单次测量开销从 ~500ns 降至 ~80ns

2. Alloc CPU 缓存行争用

  • 问题:多线程环境下,未对齐的 ThreadAllocStats 结构体导致严重的缓存伪共享
  • 解决:添加 #[repr(align(64))](缓存行填充),8线程场景下性能提升 86%
1
2
3
4
5
线程数  优化前      优化后      改善
1 ~210ms ~210ms 0%
2 ~720ms ~215ms 70%
8 ~3700ms ~500ms 86%
12 ~4400ms ~660ms 85%

3. 异步函数内存追踪

  • 问题:异步函数可能在多个线程间迁移,导致 thread_local 数据混乱
  • 解决:将 instrumented 函数包装为 InstrumentedFuture,在每次 poll() 调用时同步执行 push/pop 分配栈

4. CPU采样符号解析

  • 从二进制文件中提取符号地址范围(使用 object crate)
  • 通过 samply 的 JSON 输出(hp.json.gz)手动解析栈帧链表来归因 CPU 样本
  • 支持 exclusive(仅叶子函数)和 inclusive(含父函数)两种归因模式
  • 使用 threadCPUDelta 而非采样计数来计算 CPU 百分比,避免将”parked”状态的线程误归因为高 CPU 使用

4. Bun 的 Rust 重写计划:为什么 Zig 不够安全

来源:Bun 仓库 rust-rewrite-plan.md

Bun 的创始人 Jarred Sumner 发布了一份 924行的增量重写计划,计划将约 70.5万行 Zig 代码逐步迁移到 Rust。

为什么重写?

对最近150个已合并 PR 的分析揭示了惊人数据:

Bug 类别 数量 Rust 能防止?
错误路径遗漏清理 50 Drop
Use-after-free / 悬垂指针 19 ✅ 所有权/Borrow Checker
未初始化/类型混淆 6 ✅ 不可初始化 + exhaustive match
边界/整数溢出 18 ⚠️ panic 而非 UB
竞态/重入 15 ⚠️ 部分
  • 108/150 个 PR 是内存安全相关的
  • 75个 Bug 在有析构函数、移动语义和借用检查的语言中无法编译
  • 每3个PR就有1个是”错误路径遗漏释放”

“The Zig bugs are exactly the destructor/ownership-fixable kind, and the C++ side is already near the floor.”
—— Zig 的 Bug 恰好是析构函数/所有权可以修复的那一类,而 C++ 端已接近地板的残余类别。

迁移策略

采用 “绞杀榕”迁移(strangler-fig migration):

  • Zig 和 Rust 链接到同一个二进制文件
  • C++ 的 JSC wrapper 层保持不变
  • 按类逐个翻转 impl: "zig" | "rust" 标志
  • 每次翻转需通过:测试 + shadow-diff + ≤2% 性能回归
  • 零第三方异步运行时,使用 Bun 自有的 uSockets + ThreadPool

设计约束

  • 不依赖 std::fsstd::net——用 bun_sys 封装裸系统调用
  • 不使用 Tokio、Hyper、async-std
  • 每个 FFI 边界的 #[repr] 和布局均在编译时用静态断言校验

5. Burn 0.21.0:深度学习框架重大升级

来源Burn Blog

Rust 深度学习框架 Burn 发布了 0.21.0 版本,历时4个月,带来了显著性能提升。

亮点

  1. 框架开销降低最多 8.2 倍

    • 重新设计设备句柄(device handle),使用自定义通信通道替代递归互斥锁
    • 支持多工作线程流水线执行融合和 CubeCL 运行时
    • 融合模式下 overhead 降低平均 5.4倍
  2. 分布式训练重大改进

    • 重新设计可微分集合操作(differentiable collectives)
    • 设备传输加速 16-21倍(4 GPU 场景)
    • all_reduce 加速约 6倍
  3. GEMV/Top-K 内核优化

    • GEMV:CUDA 上列主序与 LibTorch 持平,CPU 上超越
    • Top-K CPU:比 LibTorch 快最高 41.8 倍(k=1, axis=0, large shape)
    • 采用通用内核方案而非特化配置集,性能可预测性更好
  4. burn-flex:轻量级 CPU 后端

    • 全 Rust 实现,无 JIT/无融合/无 autotune
    • 目标:WASM、嵌入式设备、小型模型推理
    • 替代 burn-ndarray(进入弃用路径)
  5. burn-dispatch:全局后端调度机制

    • 消除用户端 API 的 Backend 泛型参数
    • 早期实验:增量编译时间从 11秒降至 1秒以下
  6. 强化学习早期支持:新增离线策略训练循环(DQN 示例可用)


6. Ratty:带内联3D图形的终端模拟器

作者:Orhun Parmaksız | 原文

灵感来自 TempleOS 的”命令行嵌入精灵”概念,Ratty 是一个 GPU 渲染的终端模拟器。

特性

  • 光标是旋转的 3D 老鼠模型(可自定义为任何 OBJ 模型)
  • 终端本身是 3D 画布——可以拖拽旋转视角
  • 支持插入 3D 模型和精灵到终端中
  • 兼容 Kitty Image Protocol

架构

1
PTY → 终端解析 (vt100) → Ratatui 缓冲区 → GPU 纹理 (Vello) → Bevy 3D 场景

Ratty Graphics Protocol (RGP)

基于 APC 控制序列的自定义协议:

1
ESC _ ratty ; g ; <verb> [ ; <key=value> ... ] ESC \

支持四种操作:

  • s:查询支持
  • r:注册 3D 资产
  • p:放置对象到终端单元格空间
  • d:删除对象

提供了 ratatui-ratty crate,可以直接在 Ratatui 应用中嵌入 3D 图形。


7. iroh 1.0.0-rc.0:首个 RC 版本

来源Iroh Blog

Rust 模块化网络栈 iroh 经过4年开发、50+ 个版本后,发布首个 1.0 RC。

API 改进

  • Path 观察 API 重新设计:拆分为两个原语——Connection::paths() 返回借用快照,Connection::path_events() 返回事件流
  • IncomingLocalAddr:正确处理 relay 和自定义连接
  • Non-exhaustive 结构体/枚举:标记 #[non_exhaustive] 允许未来扩展
  • 部分可选功能已移出到独立仓库(DHT/mDNS Address Lookup → iroh-address-lookups
  • MSRV 提升至 1.91

8. “尊重式” YAML 补丁

作者:Evgeniy Terekhin | 原文

对不损坏原始 YAML 格式和注释的编程式编辑方案进行了系统评测。

评测结果

保留格式 保留注释 结论
yamlpath + yamlpatch ⚠️ 几乎完美 当前最佳选择
yaml-edit ❌ 缩进错误 ❌ 外层注释丢失 结构损坏
rust-yaml ❌ 注释散落重复 不合格
yamp ❌ 解析报错 不合格
serde_yaml N/A N/A 已停止维护

注意事项

  • Op::Replace 不支持序列类型,需要用 Append+Remove 旋转替换
  • 不支持 flow-style 列表
  • 删除空分组时,分组上方的注释可能漂移到附近行

9. The Embedded Rustacean 第71期 亮点

  • uFerris 学习板正式发货:预连线外设的嵌入式 Rust 学习平台,支持 XIAO 系列控制器
  • Zed 发布 1.0
  • Ubuntu 26.04 LTS 内置 Rust 工具:提升内存安全
  • AI 设计 RISC-V CPU:AI Agent 从零设计 RISC-V CPU
  • Rust vs C 嵌入式对比研究发布

Rust 项目更新

编译器

  • **#148214**:将 Result<T, Uninhabited>ControlFlow<Uninhabited, T> 视为等价于 T 用于 must-use lint
  • **#156173**:减少全局 node_id_to_def_id 查找
  • **#155023**:引入移动表达式 move($expr)
  • **#156185**:及早评估私有可见性,优化可见性计算(typenum crate 上最高 8% 性能提升)

标准库

  • **#149362**:添加 Command::get_resolved_envs
  • **#144537**:添加 Drop::pin_drop 用于固定析构
  • **#154025**:为 TcpStream 添加 keepalive/set_keepalive
  • **#156204**:实现 PathBuf::into_string

Cargo

  • **#16981**:追踪 Cargo 诊断警告/错误计数
  • **#16985**:键入 cargo rustfmt 时建议 cargo fmt

Clippy

  • **#16486**:新 lint inline_trait_bounds
  • **#16617**:新 lint manual_clear

Rust Analyzer

  • 支持 deref 模式
  • 新增 E0436、E0529 诊断
  • 修复 toggle_macro_delimiter 在无关位置的提示
  • 修复异步函数中 self 绑定处理
  • 移除 make mut 功能

编译器性能

总结:本周总体略微改善

  • 主要回归:0.3%(62个测试用例)
  • 主要改善:**-1.7%**(18个测试用例)
  • 2个回归、2个改善、5个混合

本期 Crate

cloakrs —— 用于检测和遮蔽个人身份信息(PII)的库和 CLI 工具。


RFC 动态

已批准的 RFC

  • **RFC #3931**:Rust 基金会维护者基金(Maintainer Fund)
  • **RFC #3945**:Cargo 中 default-features 的继承

最终评论期(FCP)

Rust

  • core::ffi::c_void 作为返回类型的 lint
  • avr 目标上 c_double 改为 f32
  • 稳定化 rustdoc 的 --remap-path-prefix
  • c_variadic 稳定化追踪
  • Path::is_empty 稳定化
  • 整数格式化到固定大小缓冲区
  • ambiguous_glob_imports lint 部分转换为硬错误

RFC

  • crates.io 用户名身份概念提案
  • Cargo 最小发布年龄(min publish age)

即将到来的活动

重点活动

时间 地点 活动
5月18-23日 荷兰 Utrecht RustWeek 2026
5月20日 温哥华(混合) Mouse Control with Rust
6月5日 虚拟 Scientific Computing in Rust 2026 CFP 开放
7月8-10日 虚拟 Scientific Computing in Rust 2026 会议
9月8-11日 加拿大蒙特利尔 RustConf 2026

本周金句

在 Bun 最近合并的150个 PR 中,108个是内存安全相关的——错误路径遗漏清理、use-after-free、未初始化读取、越界访问、重入。其中75个在有析构函数、移动语义和借用检查的语言中根本无法编译。我们每发布3个 PR,就有1个是”在某错误路径忘记释放”。

108个中约88个在 Zig 中。约14个在 C++ 中的主要是引用循环和 GC 并发竞态——这是任何语言都难以根除的残余类别。所以 Zig→Rust 的差距是真实的:Zig 的 Bug 恰好是析构函数/所有权可以修复的那一类,而 C++ 端已接近地板的残余类别。

没有更强的编译时保证,这永远是一场猫捉老鼠的游戏。提案是从结构上消除最大的 Bug 类别,而不是无限期地逐一修复。

Jarred SumnerBun 的 Rust 重写计划


This Week in Rust 由 nellshamrell、llogiq、ericseppanen 等人编辑。在 r/rust 参与讨论。

中文总结由 opencode 生成,仅供参考。

作者

1uciuszzz

发布于

2026-05-13

更新于

2026-05-13

许可协议

评论