天天看點

代碼優化經驗總結(3)

4, 函數的優化

(1)Inline函數 

在C++中,關鍵字Inline可以被加入到任何函數的聲明中。這個關鍵字請求編譯器用函數内部的代碼替換所有對于指出的函數的調用。這樣做在兩個方面快于函數調用:第一,省去了調用指令需要的執行時間;第二,省去了傳遞變元和傳遞過程需要的時間。但是使用這種方法在優化程式速度的同時,程式長度變大了,是以需要更多的ROM。使用這種優化在Inline函數頻繁調用并且隻包含幾行代碼的時候是最有效的。 

(2)不定義不使用的傳回值 

函數定義并不知道函數傳回值是否被使用,假如傳回值從來不會被用到,應該使用void來明确聲明函數不傳回任何值。 

(3)減少函數調用參數 

    使用全局變量比函數傳遞參數更加有效率。這樣做去除了函數調用參數入棧和函數完成後參數出棧所需要的時間。然而決定使用全局變量會影響程式的子產品化和重入,故要慎重使用。 

(4)所有函數都應該有原型定義 

一般來說,所有函數都應該有原型定義。原型定義可以傳達給編譯器更多的可能用于優化的資訊。 

(5)盡可能使用常量(const) 

盡可能使用常量(const)。C++ 标準規定,如果一個const聲明的對象的位址不被擷取,允許編譯器不對它配置設定儲存空間。這樣可以使代碼更有效率,而且可以生成更好的代碼。 

(6)把本地函數聲明為靜态的(static) 

  如果一個函數隻在實作它的檔案中被使用,把它聲明為靜态的(static)以強制使用内部連接配接。否則,預設的情況下會把函數定義為外部連接配接。這樣可能會影響某些編譯器的優化——比如,自動内聯。

(7) 盡量減少中間變量(編譯器多數情況下會幫你優化).

如,  obj o= getsomeObj();

Aobj ao = getAsomeObj(o); 

Int a = ao.value;

If(a==9)

可以寫成if((getAsomeObj(getsomeObj()).value) == 9);

5,計算優化

(1), 求模(餘)運算優化,如用a=a&7代替 a=a%8; 位操作隻需一個指令周期即可完成,而大部分的C編譯器的“%”運算均是調用子程式來完成,代碼長、執行速度慢。(通常,隻要求是求2n方的餘數,均可使用位操作的方法來代替) 

(2), 平方或多次方運算優化, 如用a*=a;代替a=pow(a, 2.0); 注意多次方效率更明顯,在有内置硬體乘法器的單片機中(如51系列),乘法運算比求平方運算快得多,因為浮點數的求平方是通過調用子程式來實作的,在自帶硬體乘法器的AVR單片機中,如ATMega163中,乘法運算隻需2個時鐘周期就可以完成。既使是在沒有内置硬體乘法器的AVR單片機中,乘法運算的子程式比平方運算的子程式代碼短,執行速度快

(3),盡量用位移來代替乘法和除法. 如用a=(a<<3)+a代替a=a*9

(4) 盡量避免不必要的整數除法, 整數除法是整數運算中最慢的,是以應該盡可能避免。一種可能減少整數除法的地方是連除,這裡除法可以由乘法代替。這個替換的副作用是有可能在算乘積時會溢出,是以隻能在一定範圍的除法中使用。如用m = i / (j * k) 代替m = i / j / k