More Effective C++讀書筆記---效率

效率
在用C++寫出高效地程序之前,必須認識到C++本身絕對與你所遇到的任何性能上的總是無關。如果想寫出一個高效的C++程序,你必須首先能寫出一個高效的算法
十六、條款16--牢記80-20準則(80-20 rule)
1.80-20準備說的是大約定俗成20%的代碼使用了80%的程序資源;大約20%的代碼耗用了大約80%的運行時間;大約20%的代碼使用了80%的內存;大約20%的代碼執行80%的磁盤訪問;80%的維護投入於大約20%的代碼上,也就是說,軟件的整體性能取決於代碼組成中的一小部分
2.用profiler程序識別出令人討厭的程序的20%部分。讓它去直接的測試你感興趣的資源
十七、條款17--考慮使用lazy evaluation(懶惰計算法)
1.從效率的觀點來看,最佳的計算就是根本不計算。關鍵是要懶惰
2.當你使用了lazy evaluation後,採用此種方法的類將推遲計算工作直到系統需要這些計算的結果。如果不需要結果,將不用進行計算
3.引用計數
4.區別對待讀取和寫入:殘酷的事實是我們如何判斷是讀取操作還是寫入操作,通過使用lazy evluation和條款M30中講述的proxy class,我們可以推遲做出是讀操作還是寫操作的決定
5.Lazy Fetching(懶惰提取)
6.Lazy Expression Evaluation(懶惰表達式的計算)
7.應用:能避免不需要的對象拷貝,通過使用operator[]區分出讀操作,避免不需要的數據庫讀取操作,避免不需要的數字操作
十八、條款18--分期攤還期望的計算
1.這個條款的核心就是over-eager evaluation(過度熱情計算法):在要求你做某些事情以前就完成它們
2.隱藏在over-eager evaluation後面的思想是如果你認爲一個計算需要頻繁進行,你就可以設計一個數據結構高效地處理這些計算需求,這樣可以降低每次計算需求時的開銷
3.採用over-eager最簡單的辦法就是caching(緩存)那些已經被計算出來而以後還有可能需要的值
4.caching是一種分攤期望的計算開銷的方法,prefetching(預提取)是另一種方法。你可以把prefetch想像成購買大批商品而獲得的折扣,以空間換效率
十九、條款19--理解臨時對象的來源
1.在C++中,真正的臨時對象是看不見的,它們不出現在源代碼中。建立一個沒有命名的非堆對象會產生臨時對象。這種未命名的對象通常在兩種條件下產生:爲了使函數調用而進行隱式類型轉換和函數返回對象時
2.僅當通過傳值(by value)方式傳遞對象或傳遞常量引用(reference-to-const)參數時,纔會發生這些類型轉換。當傳遞一個非常量引用(reference-to-non-const)參數對象,就不會發生
3.C++語言禁止爲非常量引用產生臨時對象的原因:當程序員期望修改非臨時對象時,對非常量引用進行的隱式類型轉換卻修改臨時對象,這是不希望看到的
4.臨時對象是有開銷的,所以你應該儘可能地去除它們,然而更重要的是訓練自己尋找可能建立臨時對象的地方
二十、條款20--協助完成返回值優化
1.通過constructor argument而不是直接返回對象能讓編譯器消除臨時對象的開銷(這是編譯器內部的優化)
二十一、條款21--通過重載避免隱式類型轉換
1.在C++中有一條規則是每一人重載的operator必須帶有一個用戶自定義的參數
二十二、條款22--考慮用運算符的賦值形式(op=)取代其單獨的形式(op)
1.從零開始實現operator+=和-=,而operator+和operator-則是通過調用前述的函數提供自己的功能。使用這種設計方法,只用維護operator的賦值形式就行。而且如果假設operator賦值形式在類的public接口裏,這就不用讓operator的單獨形式成爲類的友元
2.如果你不介意把所有的operator的單獨形式放在全局域裏,那就可以使用模板來替代單獨形式的函數的編寫:
template< typename T >
const T operator+( const T& lhs, const T& rhs )
{
 return T(lhs) += rhs;
}
const T operator-( const T& lhs, const T& rhs )
{
 return T(lhs) -= rhs;
}
3.這裏指出三個效率方面的問題:一、總的來說operator的賦值形式比其單獨形式效率更高,因爲單獨形式要返回一個新對象,從而在臨時對象的構造和釋放上有一些開銷。operator的賦值形式把結果寫到左邊的參數裏,因此不城要生成臨時對象容納operator的返回值;二、提供operator的賦值形式的同時也要提供其標準形式,允許類的客戶端在便利與效率上做出折衷選擇;三、涉及到operator單獨形式的實現
二十三、條款23--考慮變更程序庫
1.程序庫的設計就是一個折衷的過程。理想的程序應該是短小的、快速的、強大的、靈活的、可擴展的、直觀的、普遍適用的、具有良好的支持、沒有使用約束、沒有錯誤的。當然這也是不存在的。爲尺寸和速度而進行優化的程序庫一般不能被移值。具有大量功能的程序庫不會具有直觀性。沒有錯誤的程序庫在使用範圍上會有限制。所以不同的設計者給這些條件賦予了不同的優先級。他們從而在設計中犧牲了不同的東西,因此一般兩個提供相同功能的程序庫卻有着完全不同的性能特徵
二十四、條款24--理解虛擬函數、多繼承、虛基類和RTTI所需的代價

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章