去臃肿化不是一种选择,而是性能逼出来的
目录
软件行业有一种很熟悉的幻觉:把一个简单的数学运算,层层包成六层间接调用的大教堂,然后再假装这叫“工程化”。
只要工作负载一上来,秒表就会把这套幻觉拆穿。速度慢一个数量级,不是风格问题,也不是审美问题,而是实打实的成本问题。于是,很多曾经被奉为原则的规则,最后都被资深工程师一条条默默推翻;而初级工程师面试时,往往还在背诵这些已经过时的“教条”。
规则不是原则,抽象也不是信仰
凌驾于常识和实际性能测试之上的规则,不是原则,只是迷信。系统一旦进入真实负载,所有抽象层都要接受同一个问题:你到底省了谁的时间,又把成本转移给了谁?
今天的去臃肿化,不是某种时髦口号,而是被现实逼出来的回归。你可以在设计评审里继续赞美架构优雅,但真正决定生死的,往往是启动时间、内存占用、尾延迟、云账单,还有凌晨三点把人叫醒的分页告警。
为什么这些新语言会冒出来
如果一门语言简单到你能把它的边界、语义和代价都吃透,那它就会带来一种久违的安全感。Zig 就是这种语言的代表之一:静态编译、产物小、行为直接,适合把那些原本被塞进层层胶水里的东西重新收拢起来。
像 Bun 这类 runtime 之所以选择 Zig 去重写原本属于 Node 生态的一部分功能,本质上不是为了“潮”,而是为了摆脱慢吞吞的执行链路和过重的历史包袱。开发者受够了等待,也受够了把简单事情做成复杂仪式。
Mojo 的出现也不是偶然。过去十几年,Python 数据科学栈把 C、C++、Fortran 这些底层能力藏在一层又一层抽象之后,导入一个 NumPy 可能就把大片原生代码拖进内存里,只为了做一个本该直接的数值计算。Mojo 追问的其实就是那个最朴素的问题:我们能不能别再把性能藏起来?
不是炒作,是基础设施在变
Rust 之所以持续被基础设施团队选中,是因为它把“安全”和“性能”放在同一张桌子上谈,而不是拿其中一个去牺牲另一个。Cloudflare 的 Pingora、Discord 的消息已读状态服务、微软在 Windows 内核相关模块里的 Rust 迁移,这些都不是演讲台上的概念秀,而是基础设施团队在真实压力下做出的选择。
Go 走的是另一条路。它不花哨,不喧哗,甚至有点克制,但它一直在默默优化垃圾回收器、继续压缩二进制体积、保持服务启动足够快。很多曾经优先选 JVM 的团队,后来开始在意云成本和冷启动速度,最后会发现:最实用的东西往往最没戏剧性。
C++ 也没有退场。Chromium 里那些对延迟极度敏感的组件,继续被 C++20 重写和打磨,因为在某些场景里,最后那几纳秒就是产品体验和事故告警之间的分界线。
还有一些领域专用语言,走得更彻底。它们不打算适配通用框架,而是直接贴着硬件写规则。像 Ampere 这样的做法,本质上是在告诉你:在云数据中心里,内存分配和运行开销,有时比开发便利性更重要。
抽象层不是免费午餐
这说明什么?说明当性能瓶颈真正到来时,我们愿意放弃那些曾经看起来神圣不可侵犯的抽象层。
但也要说清楚:语言本身救不了你,框架救不了你,云服务商更救不了你。它们只是工具。真正的问题,永远在我们构建系统的方式里。
我们总是习惯往上叠层次,仿佛多包一层就能解决所有问题。结果往往是,系统变成一个没人能完全理解的黑箱。每一层都说自己在帮你“提高效率”,最后却把复杂度、延迟和成本一起留给你自己。
该付的账,迟早要付
你的云服务器费用、你手机上那些被快速耗尽的电量、凌晨三点把你吵醒的寻呼机——这些都在提醒你,免费的午餐终究是要还的。
去臃肿化不是一种风格选择,而是一种生存约束。现在还不开始修正的团队,迟早要面对那个凌晨三点的电话。
记住,凌晨三点框架不会替你值班,得去现场的人是你。
去臃肿化不是口号,它是现实。