整理 Effective Java 書中 Item 67: Optimize judiciously 心得筆記

主旨

這條原則的核心可以用幾句老話總結:

  • “為了效能而犯的錯,比任何原因都多。”
  • “不成熟的優化是問題根源。”
  • “規則是:1. 不要優化;2. 如果你是高手,還是先別優化。”

➡️ 寫出結構清楚、可維護的程式碼,比過早優化重要得多。 等你真正碰到效能瓶頸時,再根據實測結果有的放矢地進行優化。


不要犧牲架構原則換取效能

寫好程式比寫快程式更重要:

  • 良好的程式架構才能讓你「之後」容易優化
  • 好架構=資訊隱藏與模組化,讓你能調整內部細節不影響整體。

例如:

  • 若 API 暴露了太多內部細節(例如 mutable public fields),之後為了兼容,反而無法改進效能。
  • 若設計初期就選錯資料格式或 wire protocol,將來就算重寫演算法,也救不了很慢的系統。

但也不能完全忽略效能考量

設計階段就該注意效能會受限的地方:

  1. API 設計錯誤 → 讓你陷入性能死胡同

    • 例如 getSize() 回傳 Dimension(mutable),就得每次都產生新物件。
    • 若當初 Dimension 設計成 immutable,或 getWidth()getHeight() 分開就不會有這問題。
  2. 資料格式、協議設計不當 → 無法修補

    • 如大型 JSON over HTTP vs binary protocol(例如 gRPC)。

小提醒:

好的 API 設計 通常自然也有良好效能,不要因為追求一點點效能,把 API 設計搞爛,將來會後悔。


真的需要優化時,請這樣做

  1. 先寫出正確、清楚、乾淨的程式碼。
  2. 用 profiler 工具測試效能瓶頸在哪裡。
  3. 針對問題進行優化。每次改完都測一次。
  4. 先換演算法,再做底層微優化。

可用的工具:

  • Java Profiler:如 VisualVM、YourKit,找出時間都花在哪個方法上。
  • JMH (Java Microbenchmark Harness):專門做 method 級別的細緻效能分析。

常見錯誤:

錯誤觀念更正思維
提早優化以防萬一你只會浪費時間在沒意義的地方
猜猜看哪裡卡慢然後改寫用 profiler 測過再動手
效能不好就狂用 cacheCache 無效時反而拖累效能
先寫出快的,再來整理架構你會陷入難以維護又無法調整的程式

小結

建議原因與提醒
✅ 寫出清楚、可維護的程式碼好架構才能優化,壞架構只會綁死自己
✅ 設計 API 時就要考慮未來擴充與效能影響API 一旦公開,很難再改
✅ 真正需要效能時,再使用 profiler 做實證分析猜是沒用的,得靠測量數據
✅ 優化順序:先換演算法 → 再微調實作O(n²) 換成 O(n log n) 才是王道

想到一個故事,我之前的老闆是一個追求效率的狂人,他會要求我們所有設計都效能至上,甚至犧牲架構或維護性。要求我們造很多輪子,很多新進的工程師看到專案都苦不堪言,服務器每天必須重啟一次釋放記憶體。。。我想這也是另一總體驗。