核心概念

Rob Pike 是 Go 語言的共同創作者,曾在貝爾實驗室工作,是 Unix 的主要貢獻者之一。1989 年,他在 Bell Labs 內部撰寫了一份關於程式設計複雜度的文件,提出五條守則,距今三十多年仍廣泛流傳於工程師社群。

這五條守則的核心精神不是給你一套「怎麼寫快程式碼」的技巧,而是在告訴你何時不需要優化、為何簡單比複雜有價值、以及資料結構比演算法更根本

守則一:你無法預測效能瓶頸

效能問題往往出現在意想不到的地方。Pike 的原始表述是:「你不知道程式把時間花在哪裡。」這意味著直覺式的效能優化通常是在錯的地方浪費力氣,甚至引入複雜度和 bug。

工程師常見的陷阱是「我覺得這裡可能很慢,所以我要優化它」——但在沒有資料支撐的情況下,這種判斷幾乎都是錯的。

守則二:先量測

「先量測,才能判斷什麼需要優化。」即使量測過後,只有在某段程式碼確實拖垮整體效能時,才值得動手改。

這是 YAGNI(You Aren't Gonna Need It)的效能版本:不量測就不優化,不量測就不知道問題在哪。現代 profiling 工具(如 Go pprof、Python cProfile)讓這件事變得相對容易,但許多工程師仍習慣憑感覺動手。

守則三:小 n 時複雜演算法反而更慢

這是工程師最容易忽略的守則:複雜演算法的常數成本(constant factor)往往很高。O(n log n) 的快速排序,在 n=10 時可能比 O(n²) 的插入排序慢,因為前者的記憶體局部性差、遞迴開銷大。

「現實中 n 通常都很小」——大多數應用的資料量根本達不到讓複雜演算法發揮優勢的規模。

守則四:簡單演算法和資料結構比花俏的更好

複雜的演算法有更多邊界情況、更難除錯、更難維護。Pike 的建議:能用 array 就別用 linked list,能用 linear scan 就別用 B-tree,除非你有確實的理由。

可讀性和可維護性是長期成本最小化的關鍵。一個「次優但簡單」的方案,比一個「最優但難懂」的方案,在整個產品生命週期中成本往往更低。

守則五:資料才是核心

「如果你選對資料結構,並且把資料組織得夠好,演算法幾乎都會不證自明。程式設計的核心不是演算法,而是資料結構。」

這句話後來被 Linus Torvalds 呼應:「壞程式設計師在乎程式碼,好程式設計師在乎資料結構及其關係。」設計一個系統時,先把資料的形狀想清楚,程式邏輯幾乎自然浮現。

關鍵要點

  • 不要預測瓶頸:在有實測數據之前,任何效能優化的直覺都不可信
  • 量測先於優化:profiling 不是可選步驟,是優化的前提條件
  • n 通常很小:多數應用的資料規模不足以讓複雜演算法有優勢,常數成本反而主導
  • 簡單比花俏更可靠:簡單演算法 bug 少、維護成本低,這本身就是效能的一部分
  • 資料結構決定演算法形狀:先想清楚資料怎麼存、怎麼組織,程式邏輯自然浮現

實務應用

後端資料庫設計:守則五在資料庫 schema 設計上最直接。一張 schema 設計歪掉的表,會讓所有後續查詢都需要複雜的 JOIN 或應用層修補。相反地,一個清晰的正規化設計,讓 CRUD 操作幾乎都是直觀的單表查詢。詳見 後端資料庫基礎概念

前端狀態管理:前端的 state 就是「資料結構」的體現。React 應用中,state 設計太碎(過多分散的 useState)或太扁(把巢狀物件壓平)都會導致複雜的衍生邏輯。選對 state 形狀,組件邏輯幾乎自然浮現。

AI 工具時代的反例AI 加速開發時代的軟體設計原則 中提到,AI 工具讓工程師更容易「快速產出複雜程式碼」,這恰好放大了違背 Pike 守則的風險——不量測就優化、為了「未來擴充性」引入不必要的抽象,這些模式在 AI 輔助下變得更頻繁。Pike 守則提醒我們:可讀性和簡單性是比效能更優先的預設值

延伸觀點

複雜度的累積機制:簡單系統通常不是一次被設計複雜,而是透過漸進式修補(quick fix)自然腐化。資料工程領域的觀察顯示,每個 patch 在當下都有其理由,但隨著時間累積,原本清晰的設計變成「Picasso 拼貼畫」——功能都在,但沒人真的理解全貌。這呼應了守則二:在累積複雜度之前先量測,確認問題真的存在。

Go 語言作為哲學的具體體現:Pike 的守則不只是口號,他後來設計的 Go 語言就是最直接的體現。Go 刻意移除泛型(直到 1.18 才加入)、省略例外處理的層級結構、要求明確處理 error,這些設計決策都來自「寧可讓使用者多寫幾行,也不要讓語言本身變成魔法盒」的信念。Go 在雲端基礎設施(Docker、Kubernetes)的廣泛使用,是市場對這套哲學的投票。

KISS 的四個工程效益:跨來源研究普遍支持簡單性帶來四個可量化的好處:(1) 執行效率提升(流程更線性);(2) 可讀性改善(新成員上手時間縮短);(3) bug 率降低(邊界情況更少);(4) 協作成本下降(每個人都能理解系統)。這四個效益相互強化,且都是複雜度的反函數——複雜度上升時,四者同步惡化。

反向連結

以下頁面引用了本頁: