Effective Java Item 67:明智地進行優化
整理 Effective Java 書中 Item 67: Optimize judiciously 心得筆記
主旨
這條原則的核心可以用幾句老話總結:
- “為了效能而犯的錯,比任何原因都多。”
- “不成熟的優化是問題根源。”
- “規則是:1. 不要優化;2. 如果你是高手,還是先別優化。”
➡️ 寫出結構清楚、可維護的程式碼,比過早優化重要得多。 等你真正碰到效能瓶頸時,再根據實測結果有的放矢地進行優化。
不要犧牲架構原則換取效能
寫好程式比寫快程式更重要:
- 良好的程式架構才能讓你「之後」容易優化。
- 好架構=資訊隱藏與模組化,讓你能調整內部細節不影響整體。
例如:
- 若 API 暴露了太多內部細節(例如 mutable public fields),之後為了兼容,反而無法改進效能。
- 若設計初期就選錯資料格式或 wire protocol,將來就算重寫演算法,也救不了很慢的系統。
但也不能完全忽略效能考量
設計階段就該注意效能會受限的地方:
API 設計錯誤 → 讓你陷入性能死胡同
- 例如
getSize()回傳Dimension(mutable),就得每次都產生新物件。 - 若當初
Dimension設計成 immutable,或getWidth()、getHeight()分開就不會有這問題。
- 例如
資料格式、協議設計不當 → 無法修補
- 如大型 JSON over HTTP vs binary protocol(例如 gRPC)。
小提醒:
好的 API 設計 通常自然也有良好效能,不要因為追求一點點效能,把 API 設計搞爛,將來會後悔。
真的需要優化時,請這樣做
- 先寫出正確、清楚、乾淨的程式碼。
- 用 profiler 工具測試效能瓶頸在哪裡。
- 針對問題進行優化。每次改完都測一次。
- 先換演算法,再做底層微優化。
可用的工具:
- Java Profiler:如 VisualVM、YourKit,找出時間都花在哪個方法上。
- JMH (Java Microbenchmark Harness):專門做 method 級別的細緻效能分析。
常見錯誤:
| 錯誤觀念 | 更正思維 |
|---|---|
| 提早優化以防萬一 | 你只會浪費時間在沒意義的地方 |
| 猜猜看哪裡卡慢然後改寫 | 用 profiler 測過再動手 |
| 效能不好就狂用 cache | Cache 無效時反而拖累效能 |
| 先寫出快的,再來整理架構 | 你會陷入難以維護又無法調整的程式 |
小結
| 建議 | 原因與提醒 |
|---|---|
| ✅ 寫出清楚、可維護的程式碼 | 好架構才能優化,壞架構只會綁死自己 |
| ✅ 設計 API 時就要考慮未來擴充與效能影響 | API 一旦公開,很難再改 |
| ✅ 真正需要效能時,再使用 profiler 做實證分析 | 猜是沒用的,得靠測量數據 |
| ✅ 優化順序:先換演算法 → 再微調實作 | O(n²) 換成 O(n log n) 才是王道 |
想到一個故事,我之前的老闆是一個追求效率的狂人,他會要求我們所有設計都效能至上,甚至犧牲架構或維護性。要求我們造很多輪子,很多新進的工程師看到專案都苦不堪言,服務器每天必須重啟一次釋放記憶體。。。我想這也是另一總體驗。
Read other posts