我翻譯的文檔----Symbian基本規範:代碼效率

翻譯自SDK » Developer Library » Symbian OS Guide » Essential idioms » Code efficiency
 
概要
速度和資源使用方面的代碼效率總是值得關注的,本節提出的方法對Symbian平臺的開發者來說是很常用的。
 
棧應用
應用程序中的每個線程都有一個8Kb的標準棧,應當小心地使用。因此:
Ø           除了基本類型避免值拷貝。
Ø           應該在堆上而不是棧上創建任何大的對象或數組。
Ø           通過適當的域最小化自動變量的生命週期。
最後一點可以通過下面的例子說明:
void ABadFunction()
{
    TBigObject Object1;
    TBigObject Object2;
    TBigObject Object3;
   
    GetTwoObjectValues(Object1,Object2);
    Object3=SumObjects(Object1,Object2);
    FunctionWithUnknownStackOverhead(Object3);
}
上面的代碼中,對象Object1和Object2一直佔用棧並貫穿到FunctionWithUnknownStackOverhead()的生命週期中,即使那時已不需要使用它們。它們應當在調用發生之前從棧上刪除。可以用下面的方法實現:
void ABetterFunction()
{
    TBigObject Object1;
 
    GetTotalObjectValues(Object1);
    FunctionWithUnknownStackOverhead(Object1);
}
 
void GetTotalObjectValues(TBigObject &aObject)
{
    TBigObject Object1;
    TBigObject Object2;
 
    GetTwoObjectValues(Object1,Object2);
    aObject=SumObjects(Object1,Object2);
}
通過把代碼分離到兩個函數中,你可以確保棧的使用符合需求。
 
函數重載
如果一個函數有缺省參數並經常以缺省值進行調用,應當考慮提供一個沒有參數的重載函數。這是因爲每次提供缺省參數會使編譯器在函數被調用的地方產生額外的代碼。
例如有下面的函數:
void FunctionOne(TInt aInt=0);
在代碼中經常以下面形式調用:
FunctionOne();
這時應考慮提供一個下面這樣的函數:
void FunctionOne()
{
    FunctionOne(0);
}
 
指針和引用
使用引用做爲函數參數比指針更有效率。這是因爲編譯器不得不維護空指針通過所有的轉換。
假設一個類CXxx從混合類Myyy派生:
class CXxx : public CBase,public MYyy {...};
在傳遞一個CXxx指針到參數爲Myyy指針的函數時,編譯器不得不把把指針加上sizeof(CBase),除非這個指針爲空。例如cp是一個CXxx指針並且Func()的參數爲Myyy指針,在執行Func(cp)調用時就會像下面這樣:
Func((MYyy* aM)(cp==NULL ? NULL : (TUint8*)cp+sizeof(CBase)));
因爲引用不能爲空,所以在使用時不用判斷它是否爲空。在ARM處理器上,CXxx*轉換到MYyy*需要8條指令,但是CXxx&轉換到MYyy&只需要2條指令。
 
浮點數運算
浮點數運算效率很低,因此有必要找出一種只使用整數運算的算法。
例如下面的例子,aTop和aBottom是Tint類型:
TReal a = (TReal)aTop;
TReal b = (TReal)aBottom;
TReal c = a/b;
TReal result;
Math::Round(result,c,0);
return (TInt)result;
可以換成下面效率更好的代碼:
return((2*aTop+aBottom)/(2*aBottom));
 
內聯函數
內聯函數通過消除函數調用來提高代碼的速度,並且保持它的模塊化特徵。然而在使用它之前需要確定兩個問題:
Ø         代碼簡潔性:有限的存儲資源意味着函數調用的開銷要比使用很大的內聯函數更好。
Ø         二進制兼容性:更改內聯函數的實現會破壞程序的二進制兼容性。如果代碼要被其他開發者使用這點是很重要的。
內聯函數通常在下面的情況中使用:
Ø         取得和設置一到兩個機器字的值,例如:
inline ConEnv() const { return iConEnv; };
Ø         T類的簡單構造函數:
inline TPoint::TPoint(TInt aX, TInt aY) { iX=aX; iY=aY; };
Ø         在瘦模板中的用法:參考:SDK» Developer Library » Symbian OS Guide » Essential idioms » Thin templates
Ø         那些映射其它運算的函數,並且確定其中的運算符,函數或模板的定義不輕意改變,例如:
template <class T> inline T Min(T aLeft,T aRight)
{ return(aLeft<aRight ? aLeft : aRight); }
 
刪除指針時不用做是否爲空的判斷
C++規定delete 0不做任何事,因此從不需要寫下面類似的代碼:
if (iX)
    delete iX;
發佈了20 篇原創文章 · 獲贊 3 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章