Go 1.27 内存分配提速 30% 的秘密

Size-Specialized Memory Allocation

Go 1.27 引入了针对 80 字节以下小对象的 Size-Specialized Memory Allocation 机制,让内存分配速度提升 20-30%,整体程序性能最高可提升 1%。这次优化通过为不同的 span class 生成专门的 mallocgc 变体函数,利用编译器在编译期已知大小的优势,直接调用专用函数而非通用包装器 newobject。核心改进在于内存清零环节,编译器能将通用的 memclrNoHeapPointers 调用替换为直接指令,显著减少函数调用开销。尽管增加了代码量,但团队通过 AST 工具生成代码并精细调优,确保指令缓存(icache)效率不受影响。对于频繁创建 interface、string 或 slice 等常见小对象的 Go 程序,这一升级将带来立竿见影的性能提升,且无需开发者修改任何代码。

Go 1.27 包含针对 80 字节或更小分配的更快内存分配功能,分配速度可提升 20-30%,使分配密集型程序的速度提升高达 1%。
  1. pizlonator

    太有意思了!

    Fil-C 的 GC 基本上一直都有针对特定大小的分配机制,我也做过一些相关实验,手头有自己的数据。

    正如帖子所说,这里有两个潜在的收益:

    - 当编译器知道大小时,内存清零速度更快。在 Fil-C 中,我利用这一点让 LLVM 内联生成 memset,结果往往变成一些 SIMD 指令。

    - 大小类(size class)计算更快。

    有趣的是,在实际应用中,大小类计算更快这一点并没有带来真正的提速。我实现过它,这也是当前 ABI 的工作方式,但我很可能会把大小类计算移到运行时,以简化 ABI,因为反复实验表明那里并没有多少可节省的开销。这非常令人惊讶,但数据不会说谎。

    总之,很高兴看到其他快速非移动 GC 也找到了和我一样的最佳平衡点。

    (本帖由使用 Fil-C 编译的 WebKit 发布,为了更“元”一点,我正是用我描述的这套 GC 来写这篇帖子的)

同日更多故事

2026-09-18