性能優化是軟件開發過程當中必不可少,但又很困難的工做。這裏是我長期對C/C++開發的性能優化的經驗總結。
算法
性能優化必須遵循必要的原則進行。編程
優化前必須有個明確的目標。目標能夠有近期的,中期的和遠期的。緩存
而且目標必須是可達到,可量化的具體的值。性能優化
在任何優化前必須進行性能測試,獲得的測試結果必須保存下來。這些數據有以下用處:網絡
與以前的測試結果進行比較。若是沒有任何數據,僅僅靠自我推斷絕對是不可靠的。數據結構
對外公佈。這是讓同事/領導/客戶相信性能的最直接的信息。多線程
學習。屢次優化獲得的測試數據是學習和選擇高效的優化方式的最好的參照物。架構
發現熱點。若是沒有這些測試數據,咱們沒法明確的指導最大最長的耗時發生在哪裏。這是優化的前提。併發
性能優化的任何方法和嘗試,以及獲得的測試數據都應該記錄下來。數據結構和算法
性能測試在很大程度上實際就是壓力負載測試。對於這類的性能不須要儘量的加大數據壓力,測試對應的性能。
另外一個必需要進行屢次反覆的相同測試,並執行相關的數理統計計算。有些產品和流程只有運行幾百萬次才能真正說明性能。這個是很是重要的。
性能優化不是改變功能。
因此這些都應該基於重構的原則進行,這就意味這任何性能優化不能對上層客戶代碼形成影響。若是這是沒法避免的,必須明確說明。
發現了熱點後,咱們必須將從最大的耗時着手。2/8原則有兩層含義:
最爲耗時最影響性能的熱點僅佔全部代碼或者流程的很是小的比例;
僅對很小的一部分的代碼執行優化,性能便可獲得極大提高,甚至達到預訂目標。
因此咱們不能盲目的優化,更不能以本身的推斷或者所爲的「理論上是這樣的」想法執行優化,必須實事求是。
不少時候咱們執行優化時是在debug模式下執行的,可是最終咱們造成release模式下的性能數據。若是其中加入了爲了記錄性能的debug代碼,那麼在release模式下必須關閉。
不少場景下,可能是開發人員的性能測試指導性能優化。若是咱們將整個流程自動化,那麼能夠極大的提高優化效率,更快發佈。另外自動化最大的好處是能夠將該過程嵌入測試人員測試過程,或者自動化測試/集成/交付(CI/CD)。
可是這是很是困難的,因此須要視狀況而定。
咱們的性能優化以及獲得的結果必須是真實可信的,不能有半點做假和推測。
性能測試是咱們優化的第一步。良好的測試方法是好的開始,而不良甚至錯誤的測試方法會得出錯誤的結果。
優化的方法有不少,可是這不意味着全部的方法在每一個場景下都是可用的。
能夠分爲宏觀和微觀兩個層次:宏觀主要是基礎設施以及工程設計的優化,這個層面是不會對實現作很大變更的;而微觀則是對具體的編碼調整,內部調整可能會很是大。
硬件升級:這是最直接,有時甚至是最高效的優化方法。
操做系統升級:新的操做系統版本擁有更好的性能表現,特別是在內核操做以及內存操做方面。
編程語言:使用其餘更好的編程語言,或者更加符合性能表現的編程語言也是經常使用的性能優化方法。
編譯器:不少語言擁有不一樣的編譯器,不一樣的編譯器獲得可執行程序性能有時差異很到。而同一個編譯器的不一樣版本也有不一樣的性能表現。
臨時變量
成員變量
靜態變量
函數參數和返回值
動態內存分配
內存池
內存拷貝
緩存
阻塞和同步
無鎖隊列
內存映射
共享內存
使用模板和範型替換繼承
錯誤碼替換異常
字符串
浮點
遞歸
搜索
排序
網絡通訊
文件讀寫
用戶態和內核態的切換
編譯期計算
編譯選項
內聯-inline
新的語言版本性能更好;
新的語言版本提供了更好性能工具和特性的選擇;
新的內存佈局;
新的內存管理方式。
在不少時候優化可能得出徹底相反的結果,即性能反而更糟糕。這是很是正常的,優化路線可能很曲折漫長。有些熱點須要長時間嘗試不一樣的方法纔能有效優化。
因此耐心和信心是優化過程當中必備的良好心理素質。