性能管理通常被視為一種巫術,因為性能問題通常在應用程序開發完成之後 才會出現。到那時,就難以確定它們的根源。然而,一旦十分准確地確定了性能 問題的起因,那麼修正它常常是比較簡單的事情。工程師在尋找更有效的方法來 執行特殊任務方面通常具有相當的創造性(有時他們的創造性過了頭)。對於任 何給定的性能問題,通過使用高速緩存來減少冗余計算或者只是添加更多的硬件 ,解決方案可能會與用更有效的算法進行替換一樣簡單。但是,要清楚地確定性 能問題的根源會很困難,而設計復雜程序甚至 更加困難,所以首先要使它們沒 有性能問題。
雖然編程決策 ― 如算法或數據表示的次優(sub-optimal)選擇,無法重用 先前計算的結果,或者糟糕的資源管理 ― 通常被認為是性能問題的直接起因, 但大多數性能問題還有一個更深的起因:無法首先將性能管理、目標和測量集成 到開發過程中。
問題?什麼問題?
您如何知道何時有性能問題呢?對於大多數開發團隊,回答(用美國高級法 院法官 Potter Stewart 對罪行描述的話來講)是:在遇到時才知道。這是問題 的核心 ― 性能目標、度量和測量常常沒被考慮到,直到發現時,已經太晚了。
最常見的性能管理策略是……也沒什麼,它通常采用下列兩種形式之一:
在應用程序開發完成之前完全忽略性能
開發時進行優化,這通常意味著只關注極微小的性能考慮事項,而忽略較大 的方面
這兩種策略共有同一個基本問題 ― 它們沒有將性能管理視作開發過程的一 個集成部分。
有缺陷的性能策略 A:完全忽略性能
第一種方法是完全忽略性能,該方法將性能視作可以在項目結束時處理的事 情,比如象編寫發行說明或構建安裝程序。該策略基本上靠運氣,因為計算機運 算速度一年比一年快,所以在性能方面總能夠應付得過去。
這種靠運氣的問題(即使當成功的可能性非常大時)就是:當出現性能問題 時,您沒有處理它、確定其根源或以特別方式解決它的框架。您也沒有在開發規 劃中安排用於性能測量和調優的時間。這有點象網站,除了安裝具有缺省配置的 防火牆外,沒有嘗試使用一個連貫的安全性策略,然後發現它們已經被竊取。您 從何處著手呢?
有缺陷的性能策略 B:開發時進行優化
另一個常見但甚至更糟的方法是讓極微小的性能考慮事項驅動體系結構和設 計決策。開發人員喜歡優化代碼,其正當理由就是它令人滿意和帶來樂趣。但是 ,就關注的代碼以及在開發周期中解決性能問題的時機而言,知道何時優化更為 重要。遺憾的是,開發人員一般無法憑直覺判斷性能問題將實際出現在應用程序 的哪個位置。結果,他們浪費了大量精力對很少執行的代碼路徑進行優化,或者 更糟的是,他們損害好的設計和開發實踐來優化早先沒有任何性能問題的組件。 當您埋頭編寫代碼時,很容易在性能問題上只見樹而不見林。
使各個代碼路徑盡可能快地運行並不保證最終產品會很好地執行。再怎麼進 行局部優化都不可能彌補根本上效率低的設計,即使將每個組件實現為盡可能的 快,也是如此。開發時優化策略用關注低級別的性能考慮事項來替代對整個項目 實施的性能策略,而且讓您無法確信您真正有一個性能策略。
開發時進行優化的許多問題之一是它忽略了優化中的固有風險。少數優化也 會使設計更佳,錯誤更少,但這些都是例外情況。通常,優化涉及性能和其它考 慮事項(如干淨的設計、明確性、靈活性和功能性)之間的權衡。優化會付出一 定的成本和風險:它可能會引入錯誤、限制代碼的功能性或者使使用或維護變得 更加困難。在承受這些成本之前,請確保值得這樣做。
將性能管理作為開發過程的一部分
從一開始就應該將性能測量和規劃集成到開發過程中,對開發和性能測量和 調優進行單獨、交錯的迭代。這意味著設定性能目標、准備性能測量方案以及在 開發代碼時經常復查代碼性能。最好將舊的測試結果保存在數據庫中,這樣您可 以容易地比較當您更改代碼時性能的變化情況。
對開發和性能進行單獨的迭代,可讓您在開發迭代期間集中精力編寫起作用 的無錯誤的代碼,如果需要的話,您還會知道不久將有一個適當的機會來改進性 能。如果您想起一個使代碼運行更快的巧妙竅門,那麼在代碼中加一個注釋以詳 細描述您的想法,但現在不要實現!現在不是進行優化的時候。 如果最終必需 這麼做,則當您關注性能時再返回來。性能優化應該由性能目標驅動,並受性能 測量支持。別的東西不過是“次要的”。
測量兩次,然後再測量幾次
測量是性能管理的關鍵元素。想一下:一個給定的妙計將使代碼運行得更快 嗎?我們准備驗證這一點。在實施妙計的 前後,使用性能測量工具來測試性能 。如果您沒有測到有改進,該怎麼辦?那麼,准備收回您的妙計。如果您測不出 有好處,那為什麼要冒破壞工作代碼的風險呢?
在性能迭代期間,測量應用程序或其組件的性能,並將它們與先前迭代的測 量比較。有些方面慢下來了嗎?找出原因。如果它達不到性能目標,那麼您不一 定非得更改它,但現在您已經獲得了有價值的、有關您更改後對性能影響的反饋 信息。
達到目標了嗎?
如果您沒有定量的性能目標和支持它們的測量規劃,那麼性能調優似乎是無 意義的。您如何知道您已經達到目標了?其它開發階段(如編碼、測試和打包) 都定義了目標 ― 實現這組功能、修正這些錯誤等等。性能階段也應該有結構和 目標。
當對性能的關注是源自於外部時(不管是客戶還是公司內的另一個部門), 具有性能目標尤為重要。當某人告訴您使程序運行得更快時,您應該先問一下“ 我必須使它快多少?”否則,您可能會在調優方面投入過多的資源,但仍不能使 客戶滿意。投入十二分的精力來使程序運行速度提高 30%,不料卻有人反應“哎 呀,我原希望速度能提高 50%。”,這會讓人很失望。
結束語
性能管理不僅包括優化,還包含許多其它東西。它有一個用於決定何時優化 何時不優化的框架。您應該根據明確的性能目標、測量和規劃來做這些決策,而 不是直覺。