1. 程式人生 > >C++語言特性

C++語言特性

確實有一些操作或者C++的一些語言特性比其他因素更容易成為程式的瓶頸,一般公認的有如下因素。 (1)缺頁:如第四章中所述,缺頁往往意味著需要訪問外部儲存。因為外部儲存訪問相對於訪問記憶體或者程式碼執行,有數量級的差別。因此只要有可能,應該儘量想辦法減少缺頁。 (2)從堆中動態申請和釋放記憶體:如C語言中的malloc/free和C++語言中的new/delete操作非常耗時,因此要儘可能優先考慮從執行緒棧中獲得記憶體。優先考慮棧而減少從動態堆中申請記憶體,不僅僅是因為在堆中開闢記憶體比在棧中要慢很多,而且還與"儘量減少缺頁"這一宗旨有關。當執行程式時,當前棧幀空間所在的記憶體頁肯定在實體記憶體中,因此程式程式碼對其中變數的存取不會引起缺頁;相反,從堆中生成的物件,只有指向它的指標在棧上,物件本身卻是在堆中。堆一般來說不可能都在實體記憶體中,而且因為堆分配記憶體的特性,即使兩個相鄰生成的物件,也很有可能在堆記憶體位置上相隔很遠。因此當訪問這兩個物件時,雖然分別指向它們指標都在棧上,但是通過這兩個指標引用它們時,很有可能會引起兩次"缺頁"。 (3)複雜物件的建立和銷燬:這往往是一個層次相當深的遞迴呼叫,因為一個物件的建立往往只需要一條語句,看似很簡單。另外,編譯器生成的臨時物件因為在程式的原始碼中看不到,更是不容易察覺,因此尤其值得警惕和關注。本章中專門有兩節分別講解物件的構造和析構,以及臨時物件。 (4)函式呼叫:因為函式呼叫有固定的額外開銷,因此當函式體的程式碼量相對較少,且該函式被非常頻繁地呼叫時,函式呼叫時的固定額外開銷容易成為不必要的開銷。 C語言的巨集和C++語言的行內函數都是為了在保持函式呼叫的模組化特徵基礎上消除函式呼叫的固定額外開銷而引入的,因為巨集在提供效能優勢的同時也給開發和除錯帶來了不便。在C++中更多提倡的是使用行內函數,本章會有一節專門講解行內函數。