Google 效能優化之道:實戰技巧與工程思維 Google 兩位傳奇傑出工程師Jeff Dean 和Sanjay Ghemawat 撰寫的經典技術指南,基於Google 多年來在建立高效能軟體中的實戰經驗,總結了一套關於效能優化的原則和具體技巧。 核心理念:重新審視“過早優化” 開篇即糾正了業界對Donald Knuth 名言「過早優化是萬惡之源」的常見誤解。 · 關鍵的3%:Donald 的原意是不要在非關鍵程式碼上浪費時間,但在關鍵的3% 程式碼路徑上,我們絕不能放棄優化的機會。 · 工程素養:在成熟的工程學科中,12% 的性能提升是巨大的成就,不應被視為微不足道。 · 預設高效:不要總是以此為藉口寫出低效代碼。在不顯著增加程式碼複雜度或降低可讀性的前提下,在編寫程式碼時就應預設選擇更有效率的替代方案。 方法論:估算與測量· 培養直覺:優秀的工程師需要具備「信封背面演算」的能力。你需要對電腦底層操作的耗時量級有清楚的認知。這種直覺能幫你直接過濾掉低效率的設計方案。 · 測量為王:不要盲目猜測瓶頸,效能分析是第一個工具。 · 面對「平坦」的Profile:當你發現效能圖表中沒有明顯的「熱點」函數時,表示低垂的果實已被摘完。此時需要注意微小的最佳化累積、循環結構的調整、或從更高層級進行演算法重構。 實戰技術指南文章列舉了大量具體的程式碼變更作為案例,主要涵蓋以下幾個維度: A. 記憶體與資料結構(這是優化的重頭戲) · 緊湊佈局:現代CPU 的快取非常寶貴。優化記憶體佈局,讓經常一起存取的資料在實體記憶體上相鄰,可以顯著減少Cache Miss。 · 用索引取代指標:在64 位元機器上,指標佔用8 位元組。如果可能,用較小的整數索引代替指針,不僅節省內存,還能保持資料的連續性。 · 扁平化儲存:盡量避免使用節點式容器(如std::map, std::list),它們會造成記憶體碎片。優先使用連續記憶體容器(如std::vector, absl::flat_hash_map)。 · 小物件最佳化:對於通常元素很少的集合,使用「內聯儲存」的容器(如absl::InlinedVector),避免在堆疊上分配記憶體。 B. API 設計與使用· 批次介面:設計支援一次處理多個元素的介面。這可以減少函數呼叫開銷,更重要的是可以分攤鎖的獲取成本。 · 視圖類型:函數參數盡量使用std::string_view 或absl::Span,避免不必要的資料拷貝。 C. 減少記憶體分配· 記憶體分配不便宜:它不僅消耗分配器的時間,還會破壞快取局部性。 · 預留空間:如果你大概知道向量的大小,務必先呼叫.reserve(),避免因擴容導致的多次拷貝。 · 物件重複使用:在循環中,將臨時變數的宣告提升到循環外,避免反覆建構和析構。 · Arena 記憶體池:對於複雜且生命週期一致的一組對象,使用Arena 分配器可以大幅提高效能並簡化析構。 D. 演算法改進· 這是提升性能的「核武」。將O(N²) 的演算法最佳化為O(N log N) 或O(N) 帶來的收益遠超過程式碼層面的微調。 · 案例:文章展示如何透過簡單的雜湊表尋找替代排序後的集合交集運算,從而大幅降低時間複雜度。 E. 避免無用功· 快速路徑:針對最常見的情況編寫專門的處理邏輯。例如,處理字串時,如果全是ASCII 字符,就走快速通道,避免進入複雜的UTF-8 解碼邏輯。 閱讀原文
正在加载线程详情
正在从 X 获取原始推文,整理成清爽的阅读视图。
通常只需几秒钟,请稍候。
