C 應用程式效能優化筆記(四) 建構函式效能

2021-06-01 06:58:11 字數 1938 閱讀 5851

容易成為效能瓶頸的c++語言特性

對程式的效能問題,根本原因並非採用什麼語言編寫程式。如果程式的框架設計不作修改,單純地把乙個c++程式用c或者彙編改寫,也不能保證總體效能會有提高。因此,正確的思路應該是:首先檢查和反思程式的總體框架,然後用效能檢測工具對實際執行進行準確測量,找出關鍵路徑和瓶頸所在,然後針對瓶頸進行分析和優化。

一些容易成為程式瓶頸的c++語言特性或操作如下:

缺頁。缺頁往往意味著需要外部儲存,因此需要盡量避免

從堆中動態申請和釋放記憶體。要盡可能優先考慮從執行緒棧中獲得記憶體,因為堆比棧慢許多,而且堆一般不可能都在物理記憶體中,從堆中生成的物件,指標在棧上,本身卻在堆中,即使相鄰生成的兩個物件,記憶體位置上也可能相隔很遠。因此用指標引用這些物件時,很可能會造成缺頁。而當前棧幀空間所在記憶體頁肯定在物理記憶體中,對棧中的變數訪問則不會引起缺頁。

複雜物件的建立和銷毀。物件建立只需要一條語句,卻可能是乙個深層次的遞迴呼叫。另外,臨時物件也是要高度警惕的。

函式呼叫。函式呼叫有固定的額外開銷,呼叫頻繁時,容易造成不必要的開銷。巨集和內聯函式都是為了消除這些固定額外開銷。提倡使用內聯函式,巨集不便開發者進行開發和除錯。

建構函式和析構函式效能分析

建立乙個物件,首先需取得所需的記憶體,然後在該記憶體上執行建構函式。

建立物件時,如果從執行緒執行棧中建立(區域性物件,語句類似object obj;),則在程式進入其作用域時,該物件的記憶體已經分配好了(一般都是通過移動棧指標),object obj;一句只需呼叫建構函式,且這種建立方式不需要程式顯式地呼叫析構函式,在程式執行到該物件作用域的終點時會自動呼叫析構函式,將空間返回給執行緒棧。

如果從全域性堆中建立物件,即通過new、malloc建立,物件的指標是乙個區域性物件,需要從執行緒棧中分配,而物件本身的記憶體是從全域性堆中分配的,需要顯式呼叫delete或free來銷毀。用delete或free來銷毀物件時,會呼叫其析構函式,並將所佔的全域性堆記憶體空間返回。但從銷毀物件到程式退出該作用域,物件的指標還存在於棧中,並指向物件本來的位置。顯然,這種情況下呼叫指標是非常危險的。win32平台下訪問這種指標,結果有三種可能情況:訪問違例、取得無意義值、取得其他物件。第一種會導致程序崩潰,後兩種雖然不會立即崩潰,但是可能會有不可**的行為操作或造成物件不必要的變化,需要謹慎避免。

建構函式構造物件時分兩個步驟:初始化和執行建構函式的函式體。需要注意幾點:

--建構函式是乙個遞迴操作,即先父類後子類,父類還有父類就先構造最上面的父類。每乙個在構造時都有嚴格的順序,即按成員變數在類中的宣告順序進行初始化。故在初始化列表中成員的宣告前後實際是無意義的。盡量養成使初始化列表與成員宣告順序一致的習慣,而且還要避免用某個成員變數的值初始化另外乙個成員變數。

--千萬不要以為只有初始化列表裡列出來的成員變數才在執行建構函式體之前進行初始化的。事實上,即使沒有在初始化列表中出現,所有成員變數仍然是在初始化這一步驟(也就是在執行建構函式的函式體前)完成初始化的。所以,我們常常在建構函式的函式體內對變數進行初始化,實際是非常浪費和降低效率的。應該養成用初始化列表進行賦初值的習慣。書中有個程式,就是通過多次迴圈來檢驗在建構函式的函式體內部進行初始化對效能的影響,在迴圈足夠大的情況下,這種方法耗時是非常顯著的。

--常量和引用型成員變數必須要在初始化列表中進行初始化。以前學c++也學過這點,但是知其然不知其所以然。現在明白了,因為這兩類一旦被賦值,整個生命週期內都不能修改,而在執行建構函式的函式體前,所有成員變數已經被初始化了,所以不能在建構函式體內對其賦值。

--大型複雜系統中,如果需要生成的物件屬於乙個複雜繼承體系的末端類,則其構造會引起一長串遞迴構造,會成為消耗cpu操作的主要部分。

避免臨時變數

c/c++語言的函式呼叫都是「值傳遞」的,也就是說,在呼叫函式時,實際生成了乙個引數的副本,在函式體內部所有修改都是針對這個副本的,因此這些修改在函式結束後會全部丟失。因此,最好使用引用傳遞引數(如果不需要修改,可傳入常量引用引數),避免不必要的構造和析構操作降低效率。

C 應用程式效能優化

本文選自c 應用程式效能優化 第2版 一書 總 序 去國離家十六載後,2006年,當我再次歸來凝視上海這座不夜城時,不由地感慨世界真的變小了 變平了,中國作為地球村的一員,正以驚人的速度發展變化著。世界正改變著中國,中國也不斷影響著世界。在備感欣喜振奮之餘,我亦常常思索,在乙個越來越小 越來越平的世...

C 應用程式效能優化

本文選自一書 總 序 去國離家十六載後,2006年,當我再次歸來凝視上海這座不夜城時,不由地感慨世界真的變小了 變平了,中國作為地球村的一員,正以驚人的速度發展變化著。世界正改變著中國,中國也不斷影響著世界。在備感欣喜振奮之餘,我亦常常思索,在乙個越來越小 越來越平的世界裡,中國會面對怎樣的挑戰和機...

C 應用程式效能優化讀書筆記

粗淺的看了下,有點虎頭蛇尾。暫且記下。第一篇 c 程式優化基礎 第1章 c 物件模型 1.1 基本概念 1.1.1 程式使用記憶體區 乙個程式占用的記憶體區一般分為5種 全域性 靜態資料區 常量區 區 棧 堆。例子 include include int nglobal 100 int main v...