Firefox 使用 Rust 重写 UDP I/O
Firefox 在 2024–2025 年间用 Rust 重写其 QUIC(HTTP/3 所依赖的协议)底层 UDP I/O,提升了安全性和性能。
目前,在 Linux 系统上成功启用 GSO/GRO(UDP 分段/聚合卸载),性能显著提升(极端情况下吞吐从 <1 Gbit/s 提升至 4 Gbit/s)。在 Windows 和 macOS 上的 Firefox 由于兼容性问题,暂未启用。
原文:https://max-inden.de/post/fast-udp-io-in-firefox/
Rust 中对动态 trait 的类型擦除
在这篇文章中,作者探讨了 Rust 中的动态 trait 的类型擦除及安全还原。
核心问题
- Rust 的
Box<dyn Any>
可以存储任意类型并尝试还原,但无法直接还原为Box<dyn SomeTrait>
。例如,对于存储到Box<dyn Any>
中的Box<dyn Fn(&A) ->R>
,就无法还原回原始类型。因为每个闭包都有唯一的匿名类型,而Any::downcast_ref
在编译期要求知道确切的具体类型。 - 虽然可以将
Box<dyn Fn>
包进Box<dyn Any>
(双重装箱),但这带来额外的内存分配和间接层,不够高效。
解决方案
作者提出一种手动操作“胖指针” 的方法,利用 Rust nightly 的 ptr_metadata
特性:
- 该特性提供将胖指针拆分为数据指针和元数据指针的函数:
to_raw_parts
以及反向操作函数:from_raw_parts
。 - 对于
dyn SomeTrait
,它的元数据类型是DynMetadata<T>
,其中,T
为dyn SomeTrait
- 每个 trait 都有自己的
DynMetadata<T>
- 因此,只要我们确定类型匹配,就可以将
*const ()
转换成DynMetadata
实现成果
- 定义了一个通用结构
TypeErasedBox
。 - 基于此封装
DynFn
,能存储任意闭包。并在不知道其具体类型的情况下,通过泛型参数还原为&dyn Fn(A) -> R
并调用。
注意事项
- 该方案依赖 Rust nightly 的不稳定特性(
ptr_metadata
),不适用于 stable Rust。 - 涉及大量
unsafe
代码,需谨慎使用,作者也表示目前不会在生产 crate(如typed-eval
)中采用,更多是技术探索。
原文:https://blog.romamik.com/blog/2026-09-25-type-erased-dyn-trait/#type-erased-trait-objects-implementation
fetch_max
背后的故事
本文作者偶尔会面试一些工程师,他常问的问题之一是:“如何跟踪多个生产者线程的产生的最大值“。这属于并发编程领域常见的问题了。候选人可以使用任何他们想要的语言。例如,可以用 Java 编写一个 CAS 循环来实现。直到一位面试者选择使用 Rust 并写下了这样的代码:
high_score.fetch_max(new_score, Ordering::Relaxed);
由此开始,作者开始探索 fetch_max
背后的故事,发现了一段奇妙的旅程,它贯穿了编译器转换的五个不同层次,每一层都剥离了一层抽象,直到找到那个循环的确切实现位置。并将这个过程分享出来。
原文:https://questdb.com/blog/rust-fetch-max-compiler-journey/
--
From 日报小组 Yuan YQ
社区学习交流平台订阅:
评论区
写评论还没有评论