“轻量”的软件一般都比较新或没什么开发活动。任何一个软件系统,在有足够的历史包袱,足够的人参与,足够强的功能,足够多的用户之后,必然会有向“重量”方向发展的倾向。
绝大多数项目不 care 这一点,或者不会投入足够的资源,没有足够的能力去控制这种倾向,就会真的变成重量的软件。
到 Linux 桌面上,结果就是要么轻量但缺功能 bug 多,要么功能比较全但必然在某方面重量。需要注意这是生老病死一样的通用固定规律,不是 Linux 桌面的特色。你们 Linux 服务器上跑的服务都很轻量?嵌入式 Linux 没有屎山?一个 AI 应用带一大堆 Python 依赖很优雅?我甚至还没有开始讨论 node_modules 。
一个例子是 Clang 编译器,在刚开始时它的优点之一是编译速度比 GCC 更快:
llvm.org/pubs/2008-10-04-ACAT-LLVM-Intro.pdf但是随着项目的发展,后来逐渐有人发现它变得越来越慢:
https://web.archive.org/web/20190920024922/https://twitter.com/debiatan/status/1169632959550414848 (这是 19H2 的推,但是他测试的最新版本 4.0 是 17H1 发布的)
类似的数据可以在其他地方得到确认:
* 这是 Clang 3.5 时期的,测试中 Clang 要比 GCC 快一大截:
www.phoronix.com/review/gcc49_compiler_llvm35/2 A Quick Look At GCC 4.9 vs. LLVM Clang 3.5 - Phoronix
* 五年后的这份数据很有意思,可以看到 Clang 相对于 GCC 整体依然有编译速度的优势,但已经从“一大截”缩小到“一点”。更有趣的是它比较了 Clang 7 和 8 ,以及 GCC 8 和 9 ,可以看到每一个编译器在新版本中都有变得越来越慢的趋势:
www.phoronix.com/review/gcc-clang-2019/4 62 Benchmarks, 12 Systems, 4 Compilers: Our Most Extensive Benchmarks Yet Of GCC vs. Clang Performance - Phoronix
* 同年底的数据显示了一种 bad to worse 的发展:
www.phoronix.com/review/gcc-clang-3960x/4 LLVM Clang Performance Matching The GCC Compiler On AMD Threadripper 3960X - Phoronix
* 到了 20H2 我们在讨论什么呢?
www.phoronix.com/news/GCC-Faster-Kernel-Builds-Clang GCC Is Currently Faster Than LLVM's Clang At Compiling The Linux Kernel - Phoronix
* 后来有人直接对比了 LLVM 2.7 和 11 版本的编译速度:
zeux.io/2022/01/08/on-proebstings-law zeux.io - On Proebsting's Law
现在你已经可以随便在网上搜到一堆 Why is LLVM/Clang so slow 的帖子了。
Rust 的人讨论过这个问题,并且尝试逆转这个潮流:
www.npopov.com/2020/05/10/Make-LLVM-fast-again.html Make LLVM fast again
这篇文章有几个有意思的点,一个是 LLVM 确实在变得越来越慢,但是这个变慢的过程大多是以每个 commit 百分之零点零几的进度逐渐积累的。同样,作者试图做出一些优化,优化的过程也是一个 commit 百分之零点几一点一点做。
这个观察和 SQLite 作者 Richard Hipp 的经验不谋而合:
sqlite-users.sqlite.narkive.com/CVRvSKBs/50-faster-than-3-7-17 50% faster than 3.7.17
> We have achieved this by incorporating hundreds of micro-optimizations. Each micro-optimization might improve the performance by as little as 0.05%. If we get one that improves performance by 0.25%, that is considered a huge win. Each of these optimizations is unmeasurable on a real-world system (we have to use cachegrind to get repeatable run-times) but if you do enough of them, they add up.
就我的经验来看,一个 0.05% 的优化是很难判断到底是实际的优化,还是测量误差的。Richard Hipp 讲过他是使用 cachegrind 工具来精确测量每个 commit 前后的性能数据(这就是为什么你在主题中会看到精确到个位的 CPU 周期数,虽然他这种方式并不那么精确就是了 ...)。
我一直认为 SQLite 是个非常独特的项目,它有独特的 License (直接说是 Public Domain ,Richard Hipp 说过这其实很麻烦,因为很多大企业的法务知道怎么处理 GPL ,MIT ,Apache ,但是不知道如何处理 Public Domain 。作者在每个文件头放了三句祝福的话),独特的开发模型(开源但不开放贡献),独特的开发方式(使用 Fossil 作为 VCS ,非常全面的测试),独特的使用方式(使用 SQL 的嵌入式数据库),甚至对 SQL 也有独特的理解( Manifest Typing )。所以在“轻量”这方面,SQLite 能够跳出这种周期律。而大多数普通的项目,有多少愿意付出这种“独特”的代价呢?