用64位字替换Rust Enum让解释器提速17%

Replacing a Rust Enum with a 64-Bit Word Made My Interpreter 17% Faster

用64位字替换Rust Enum让解释器提速17%

在构建 Plush 语言解释器和虚拟机的过程中,我发现原本使用的 Rust 标记枚举虽然方便,却因内存对齐问题导致每个值占用128位,造成大量内存浪费。为了解决这个问题,我和 Claude 共同设计了一套高效的低位标记方案,将 Value 类型压缩到64位。通过利用地址对齐特性窃取低位作为标签,并针对整数和浮点数设计特殊的编码方式,我们不仅大幅降低了内存占用,还意外地让解释器整体速度提升了17%。这次优化证明了在虚拟机工程中,内存效率与执行速度并非总是零和博弈,巧妙的位操作反而能带来双重收益。

对于虚拟机工程师来说,这种因内存对齐导致的字节浪费,足以让人在深夜痛哭。
  1. fpoling

    文章标题具有误导性。问题并非 Rust 编译器无法优化某些底层操作,而是作者设计了一种编码方案,将解释器处理的大多数内容都塞进了 64 位中。这取代了之前那种所有东西都用 128 位、但能直接映射到 Rust enum 的方案。代价是不得不将某些内容分配到堆上并使用指针间接访问,不过由于这些情况只出现在罕见值上,因此平均来看新方案带来了不错的收益。

    指望编译器能自动想出这种编码方案是不现实的。

  2. lowbloodsugar

    看看 triomphe 的 ArcUnion,并由此类推。基本上就是专门为你这个 64 位联合类型写一个 crate,在那里用 unsafe 实现,然后用 miri 进行测试,这样你就有了一个可以配合 match 使用的安全 64 位类型。你很喜欢钻研汇编,所以这完全在你的能力范围内。唯一的挑战是,如果你用 miri 进行验证,就需要使用那些“保留来源(provenance-preserving)”的指针调整函数。在我看来,这绝对值得花时间去学习。我在自己的系统中做过类似的东西,过程超级有趣,而且确实取得了文中描述的性能提升。

  3. gigatexal

    但是,enum 难道不是比不得不进行位操作要可读得多、也更容易维护吗?

  4. krick

    听到这个真让人不爽。很遗憾被提醒 Rust 编译器并非魔法,不能就这么……不知怎么地搞定这些事。当然,所有抽象都有代价,但天哪,仅仅因为用这种怪物替换了 enum 就获得了 17% 的性能提升?这真让人恼火。

同日更多故事

2026-09-08