程式大小作為關鍵資源#
在 1960 至 70 年代,記憶體是極為昂貴且有限的資源。Brooks 指出,程式的大小(size)必須像時程和預算一樣受到嚴格的管理。即使在今天記憶體相對充裕的時代,這個原則依然適用——只是「稀缺資源」的對象從記憶體變成了快取、頻寬、電池壽命或啟動時間。
程式大小不會自己控制自己。如果不從一開始就設定預算並嚴格追蹤,系統會不可避免地膨脹到超出限制。
大小預算#
Brooks 主張,架構師必須為每個元件設定大小目標,就像設定時程里程碑一樣。這些預算不僅包括核心記憶體的使用量,還應涵蓋磁碟存取次數(I/O 效能)等關鍵資源。
管理者在大小控制方面的職責是:
- 從一開始就定義預算:在設計階段就為每個模組分配記憶體額度
- 持續追蹤實際值與預算的差距:定期比較實際使用量和預算
- 及早發出警報:當某個模組超標時,立即採取行動而非等到整合時才發現問題
這種做法要求在專案初期就做出看似武斷的分配決定。但 Brooks 認為,有預算總比沒有預算好——即使初始分配不夠精確,它至少提供了一個追蹤和調整的基礎。
功能與大小的取捨#
當程式無法塞進分配的記憶體空間時,就必須做出艱難的取捨。架構師需要判斷:哪些功能以最少的位元組提供最大的價值?
這是一個需要智慧和勇氣的決策。有時候,砍掉一個看起來很重要的功能,反而能讓系統整體更加精煉和有效。Brooks 強調,這些取捨決策應該由架構師而非個別程式設計師來做,因為只有架構師能從全局的角度評估每個功能的相對價值。
功能的取捨不是失敗的標誌,而是成熟的工程判斷。最好的系統不是擁有最多功能的系統,而是在有限資源下提供最大價值的系統。
空間與時間的取捨#
Brooks 提到了計算機科學中的經典原則:空間與時間的取捨(space-time tradeoff)。你可以用更多記憶體換取更快的執行速度,反之亦然。
例如:
- 查表法(lookup table)用額外的記憶體空間來避免重複計算,換取速度
- 即時運算(on-the-fly computation)用較少的記憶體但花費更多的 CPU 時間
團隊必須有意識地做出這些取捨,而非讓它們在無人注意的情況下自然發生。管理者應該明確指定哪些場景優先考慮速度、哪些優先考慮空間。
表達方式即程式設計的本質#
Brooks 引用了他的導師的一句名言,這句話可以說是本章最深刻的洞見:
「讓我看你的流程圖但隱藏你的表格,我會持續困惑。讓我看你的表格,我通常就不需要你的流程圖了;它們會不言自明。」
這句話道出了一個根本真理:資料結構(表達方式)比程式碼更重要。程式的複雜度主要來自它所操作的資料結構,而非控制流程。選擇正確的資料表達方式,往往能讓演算法自然而然地變得簡單明瞭。
當你面對一段複雜難懂的程式碼時,與其試圖簡化邏輯流程,不如先重新審視它的資料結構。很多時候,換一種資料表達方式就能讓整個問題迎刃而解。
控制程式大小的技術#
Brooks 提出了幾種控制程式大小的實用策略:
使用高階語言#
高階語言的編譯器通常能產生比手寫組合語言更緊湊的程式碼。雖然這聽起來違反直覺,但編譯器能夠利用系統性的最佳化技術,而人類程式設計師往往只能做局部的最佳化。
共享公共程式碼#
將通用的功能抽取到共享函式庫中,避免每個模組各自實作相似的邏輯。這不僅節省空間,還提高了程式碼的一致性和可維護性。
共享資料緩衝區#
透過分時使用(overlay)或分頁(paging)機制,讓不同的功能模組共享同一塊記憶體緩衝區。這種技術在記憶體有限的系統中特別重要。
精心設計資料表達#
這是最根本也最有效的策略。花時間在資料結構的設計上,往往能帶來程式大小和複雜度的大幅縮減。一個巧妙的資料結構可以同時節省空間和簡化程式碼。
不要在專案後期才開始擔心程式大小。到那時候,架構已經定型,資料結構已經選定,能夠騰挪的空間非常有限。大小控制必須從第一天開始。
本章重點#
- 程式大小是需要主動管理的關鍵資源,必須像時程和預算一樣設定目標並追蹤
- 架構師應為每個元件分配大小預算,管理者應持續監控實際值與預算的差距
- 功能與大小的取捨是成熟的工程判斷——最好的系統不是功能最多的系統
- 空間與時間的取捨必須有意識地進行,而非任由其自然發生
- 資料結構比程式碼更重要——選對表達方式,演算法就會自然簡化
- 高階語言、共享程式碼、共享緩衝區和精心設計的資料結構是控制大小的四大策略