预言与人性 — 原则管不到的地方
这一章讲五件事: 性能问题的两条戒律(别早优化、没有万能药); 布鲁克斯法则的算术;康威定律与组织编排;第二系统综合征与功能蔓延; 以及车轮和牦牛这两个自我陷阱。收尾接原书后记:回到人。 主走查:12 人月项目的排期算术(书里原例)。
1. 性能:两条同源的戒律
这一节回答:什么时候可以追求「快」——答案的形态是两条禁令,而不是一个方法。
优化(原书叫「性能调优」:让程序跑得更快、更省内存与磁盘的修改)有一条反直觉的铁律, 两条箴言的说法互相印证1:
- 「不要在编程之初就对代码进行优化」(对所有人);
- 「编程之初暂时不要对代码进行优化」(「暂时」二字是给专家留的2)。
为什么这么狠?因为过早优化是一笔六重的亏本买卖3:
| 代价 | 机制 |
|---|---|
| 可读性变低 | 优化改掉「简单直接」的逻辑,难以表达意图 |
| 质量变差 | 复杂化藏得住故障;「答不出正确答案也枉然」 |
| 复杂度增大 | 用后门强化模块依赖,失去可移植性 |
| 阻碍维护 | 不自然的描述让流程难追踪,还限制可扩展性 |
| 与环境冲突 | 为特定处理器选的数据类型,在别的处理器上反而更慢 |
| 工作量增多 | 优化本身是额外工程,找错对象=纯亏 |
深层机制,UNIX 优化原则一节讲得更透:过早优化会同时破坏透明性与简单性, 而「代码越简单,可优化之处就越容易被找到」——先优化反而堵死了后优化4。 正确顺序:先写正确、简单、可读的代码(哪怕它慢),再系统地找收益最大的地方动手5。
收益最大的地方怎么找?热点——占用大部分处理时间的那一小段代码。 书里给的调优流程是一台测量机器6:证明优化必要(用户可能根本没那么在意)→ 测量、找出热点 → 只优化热点 → 再测量(「性能差的部分是无法推测出来的」, 优化效果只能靠测量得知)→ 验证没引入新问题。 配套的一条现实感:软件整体性能的大头常在架构、中间件、库、部署这些代码之外的因素, 一行行代码的影响「十分渺小」7——所以深层的性能设计要趁早(如通信协议), 但那是设计决策,不是代码优化8。
还有一条与本书其他原则汇合的暗线:热点的存在本身就是 80:20 定律 (帕累托法则:整体中约 20% 的元素贡献约 80% 的结果)在代码上的形态—— 20% 的代码集中 80% 的故障、80% 的处理时间(实际比例「更小」)9。 这给了「先测量再动手」一个统计学的底气:优化者最大的敌人不是慢,是找错地方。
万能药:同一个错误的另一副面孔
预言的第二个灾区是工具。80-10-10 原则:再好的高水平工具, 也只能在短时间内实现用户需求的 80%;剩下 20% 里,10% 要下苦功, 10% 完全不可能——追求 100% 满足,开发就进退两难10。
这不是猜想,是全行业花十几年做过的实验:从 1990 年代中期起,业界举全行业之力 造「让平庸技术人员效率飞跃」的万能工具——这就是所谓「模型驱动开发」、4GL(第四代编程语言, 按业务概念描述程序的高级语言),结论是「用一个工具解决所有问题的万能药路线显然走不通」—— 工具的功能限制造出自己的「防守范围」,而软件要处理的问题范围是无限的11。 正确姿势:积极导入工具,但先做模拟开发验证适用范围再正式导入; 实在缺的 10%,按项目特征造「对症药」(用元编程能力强的动态语言造专用小语言)12。
与「早优化」「万能药」同源的,还有 UNIX 多样性原则那句判词: 对任何宣称「唯一正确方法」的言论都应持怀疑态度——人的想象力有限, 「『存在唯一正确的方法』这种态度既狂妄又不成熟」13。 三条戒律一句话归并:别替未来做你没有信息做的决定。
2. 布鲁克斯法则:人数和月数不可交换
这一节回答:进度落后了,加人为什么火上浇油——全书最著名的一条「法则」。
布鲁克斯法则(出自《人月神话》,布鲁克斯是 IBM 大型机系统 OS/360 的负责人): 开发进度滞后的项目,后半程添加人手,只会让进度延误进一步加重14。