build2 比 Ninja 更快:如何超越光速基准

Faster Than Ninja

Ninja 常被视为构建系统的“光速”基准,但 build2 通过原生设计和多线程优化,在 Xerces-C++ 的实测中甚至超越了它。Ninja 依赖 CMake 生成构建文件,这额外消耗了数秒时间,而 build2 作为原生系统避免了这一开销。通过禁用部分高级功能如精确变更检测和文件缓存压缩,build2 的构建时间从 3.8 秒降至 3.35 秒,比 Ninja 快 2.2%。其核心优势在于激进的缓存策略、全链路多线程处理,以及将头文件依赖提取与部分预处理结合的独特构建模型。即使承担了比 Ninja 更多的工作,build2 依然能实现更快的构建速度,证明了不同设计思路带来的性能突破。

简而言之,我们必须以不同的方式做事,而不仅仅是做得更好。
  1. evmar

    [Ninja 作者在此] 很棒的文章,很高兴看到如此深入的探讨!我也很欣赏他们对自己数据来源的详细说明。

    正如他们所观察到的,Ninja 之所以快,很大程度上是在“作弊”:它通过声明许多事情不在 Ninja 的职能范围内,从而规避了大量工作,这也意味着它是一个很好的竞速基准。(有个趣事:当初写 Ninja 时,我记错了早期构建系统的速度,所以一直试图让它更快。所以别把它当成下限,那只是我拍脑袋定的!)

    我在这里评论是想说,我觉得这篇文章对“为什么”的解释并不令人满意。他们提到了三个设计决策。

    第一个是对 CMake 的批评,而不是对 Ninja 的(?),所以我不认为这能解释原因。我是不是理解错了?

    第二个理由是并行处理一些工作,比如头文件依赖。这对我来说是最 plausible 的理由,但依然感觉不太可能。工作量非常小:文章提到 300 次编译,那可能只是解析 300 个小文本文件?

    第三个是他们在前端额外运行一次编译器来收集头文件,这严格来说比 Ninja 做了更多工作。虽然文章对文件访问模式有些含糊其辞,但我持怀疑态度;如果端到端构建时间是 3 秒,那项目小到足以全部装入内核缓存。他们还提到做其他事情,比如调用编译器获取版本信息。这似乎会完全掩盖第 2 点带来的任何性能提升。

    也许这只是我个人的 c […]

  2. bluGill

    CMake 生成这个项目花了 15 秒?我觉得 build2 不太可能在做和 CMake 完全一样的工作。当然,我得承认 CMake 是单线程的且很慢,所以有很多空间可以做得比它更好(它的语言很糟糕,这也是迫使它单线程的原因之一)。另外,如果 CMake 在做一些其实没必要的事情,我也不会感到惊讶(大概率默认编译器就能用——大多数时候检查版本并没有多大价值)。

  3. Meneth

    我想知道它和 Tup ( https://gittup.org/tup/ ) 相比怎么样。

  4. zamalek

    > 让我们看看能不能再快一点。接下来,我们在文件缓存中禁用压缩。稍后我们会更详细地讨论文件缓存,但先简单说,禁用压缩意味着我们用临时的磁盘空间换取速度:

    这里有点不对劲。这里用的是哪种压缩算法?优化程度如何?像 zram 这类工具的核心假设是:磁盘访问太慢了(即使是 NVMe),你往往可以用解压的比特率来战胜它。

    1. 是否使用了像 gzip 这样慢的算法?

    2. 压缩努力是否为了空间而过度优化了?做一些空间基准测试,确保你不是在 GB 级的数据上只省了几十 MB。

    使用 zstd,压缩等级设为 1-3(甚至可能发现负数才是整体最优),并配合训练好的字典(你的数据看起来都很相似),应该是个不错的起点。

  5. shevy-java

    性能提升固然好,但我觉得 meson/ninja 和 cmake(或 cmake/ninja)都搞错了一件事,而 GNU configure 却做对了,那就是"./configure --help"。为什么这些工具都不简单加个 --help 呢?是的,它们的语法不同,但问题不仅仅在于 --help。通常我可以通过 --disable-man 或 --disable-doc 之类的选项禁用文档或手册页。最近我和一个刚转用 ninja 的人讨论过,我认为应该有个选项可以跳过安装 man 页。他觉得每个人都需要 man 页。我告诉他,我从来不看任何本地 man 页,我只在网上查帮助。而且我已经这样做了快 30 年。我理解 70 年代 man 页的时代,但我现在用不着(我确实会收集本地文档,只是不走 man 页这条路)。他不想添加一种不安装 xmlto 或 docbook 变体(这些玩意儿安装起来很麻烦,看看 LFS/BLFS 的说明就知道,而且即使装了也往往不能干净地工作)就能安装软件的方式。Meson 和 cmake 比 GNU autotools 好,但 GNU autotools 做对的那几件事,在 meson 和 cmake 里都丢掉了,这很有趣。看来我们只能在这里选择不同的权衡方案。新并不自动意味着更好。如果功能被移除或不再可用,快 5% 真的毫无意义。

同日更多故事

2026-08-05