優(yōu)化追求
優(yōu)化主要是內(nèi)存使用與執(zhí)行速度的雙優(yōu)化。
需根據(jù)硬件條件料饥、輸入作用域蒲犬、精度、優(yōu)化的時(shí)間和精力消耗岸啡、代碼可讀性原叮、程序復(fù)雜度等全面評(píng)估。
優(yōu)化總思路
方法:
- 找出程序中執(zhí)行緩慢或占用內(nèi)存較大的地方進(jìn)行優(yōu)化——程序內(nèi)部循環(huán)重復(fù)調(diào)用、調(diào)用第三方庫(kù)最該被優(yōu)化奋隶;
途徑:
經(jīng)驗(yàn)查找擂送;
Visual C++ 內(nèi)置的性能工具 profiler 來(lái)找出程序中消耗最多內(nèi)存的地方;
英特爾的 Vtune唯欣,它也能很好的檢測(cè)出程序中運(yùn)行最慢的部分嘹吨;
優(yōu)化123
整形數(shù)
盡量使用整形代替浮點(diǎn)型(避免浮點(diǎn)運(yùn)行單元或浮點(diǎn)庫(kù)的調(diào)用),如浮點(diǎn)型只需兩位小數(shù)境氢,可以乘100變成int;
盡量使用unsigned int,如果符號(hào)已知蟀拷;
浮點(diǎn)數(shù)
嘗試定點(diǎn)數(shù)代替浮點(diǎn)數(shù);
浮點(diǎn)數(shù)盡量用float代替double;
先驗(yàn)函數(shù)
如 sin萍聊、exp问芬、sqrt 和 log 是通過(guò)一系列的乘法和加法實(shí)現(xiàn)的(使用了精度擴(kuò)展)。這些操作比通常的乘法至少慢十倍寿桨。
泰勒級(jí)數(shù)展開(kāi);
多項(xiàng)函數(shù)近似:
除法和取余
除法盡量換成乘法此衅;
除法或取余可以循環(huán)減代替;
用移位代替除法(除數(shù)是2的冪次)亭螟;
多個(gè)除法時(shí)炕柔,合并除法;
查表(更快媒佣,更能節(jié)省存儲(chǔ)空間)或近似替代代替除法;
使用常量將除法轉(zhuǎn)換為乘法陵刹,如
x=x/3.0
可以替換為x=x*(1.0/3.0)
;判斷句中除法換成邏輯關(guān)系和乘法比較形式默伍;
盡量使除數(shù)和被除數(shù)是無(wú)符號(hào)的整數(shù)(除法效率:整形>浮點(diǎn)型;無(wú)符號(hào)>有符號(hào))衰琐;
變量生命周期
由于處理器中寄存器是固定長(zhǎng)度的也糊,程序中數(shù)字型變量在寄存器中的存儲(chǔ)是有一定限制的。
限定變量的使用數(shù)量:將較大的函數(shù)拆分為小而簡(jiǎn)單的函數(shù)也會(huì)達(dá)到很好的效果羡宙;
對(duì)經(jīng)常使用到的變量采用寄存器存儲(chǔ)狸剃。
局部變量
- 盡可能的不使用 char 和 short 類型的局部變量,使用int或unsigned int代替(避免編譯器賦值時(shí)兩次的移位操作)
指針
盡可能的使用引用或指針的方式傳遞結(jié)構(gòu)數(shù)據(jù)狗热,否則傳遞的數(shù)據(jù)會(huì)被拷貝到棧中钞馁,從而降低程序的性能;
確定不改變數(shù)據(jù)結(jié)構(gòu)的值時(shí)匿刮,設(shè)置為const pointer;
盡量避免重復(fù)的指針鏈僧凰,如緩存指針鏈為局部變量:
Point3 *pos = p->pos
;
布爾表達(dá)式判斷范圍
x>min && x<max
可以轉(zhuǎn)換為(unsigned)(x-min)<(max-min)
(如為負(fù),換成無(wú)符號(hào)就肯定符合)熟丸;盡量使用與0判斷的形式训措,優(yōu)化C編譯器內(nèi)部的比較指令;
條件語(yǔ)句
如果可以,用switch語(yǔ)句代替if-else語(yǔ)句绩鸣,避免最后條件滿足時(shí)else前面條件都運(yùn)行怀大;
if條件內(nèi)如果是
&&
或||
,則應(yīng)將容易判斷的條件放在前面,這樣后面條件有時(shí)可以避免判斷呀闻;switch-case中case過(guò)多時(shí)化借,可以使用數(shù)組、映射等方法優(yōu)化总珠;
循環(huán)
使用計(jì)數(shù)到零的循環(huán)(遞減形式到0屏鳍,用0做判斷)和簡(jiǎn)單的循環(huán)終止條件;
如果可以局服,合并循環(huán)钓瞭;
循環(huán)中,總是調(diào)用函數(shù)淫奔,則將循環(huán)納入到函數(shù)(調(diào)用函數(shù)時(shí)總是會(huì)有一定的性能消耗)山涡;
-
展開(kāi)循環(huán)
循環(huán)迭代次數(shù)只有幾次,那么可以完全唆迁,以便消除循壞帶來(lái)的負(fù)擔(dān)鸭丛;
大的循環(huán)可以分解間斷著展開(kāi),然后大步循環(huán)唐责,減小循環(huán)次數(shù)鳞溉;
盡早的斷開(kāi)循環(huán),增加break環(huán)節(jié)鼠哥;
函數(shù)設(shè)計(jì)
盡量保證函數(shù)使用少于四個(gè)參數(shù)熟菲。這樣就不會(huì)使用棧來(lái)存儲(chǔ)參數(shù)值;
將參數(shù)放入一個(gè)結(jié)構(gòu)體并通過(guò)指針傳入函數(shù)朴恳,這樣可以減少參數(shù)的數(shù)量并提高可讀性抄罕;
減少全局變量的使用,使用 static 修飾變量為文件內(nèi)訪問(wèn)于颖;
盡量使用整形兼容類型(char呆贿,shorts,ints 和 floats 都占用一個(gè)字)森渐;
-
多使用葉子函數(shù)(內(nèi)部不調(diào)用其他函數(shù)的函數(shù))做入,消耗小,高效章母;
避免調(diào)用其他函數(shù):包括那些轉(zhuǎn)而調(diào)用 C 庫(kù)的函數(shù)(比如除法或者浮點(diǎn)操作函數(shù))母蛛;
簡(jiǎn)短的函數(shù)使用__inline 修飾(調(diào)用處直接替換為函數(shù)體。代碼調(diào)用函數(shù)更快乳怎,但增加代碼的大小彩郊,特別在函數(shù)本身比較大而且經(jīng)常調(diào)用的情況下)前弯;
使用 #define 宏取代常用的小函數(shù);
不使用遞歸(需要太多的函數(shù)調(diào)用);
一維數(shù)組比多維數(shù)組更快;
加法操作比乘法快,乘法比除法快秫逝;
如果你的庫(kù)支持 mallopt () 函數(shù)(用于控制 malloc)恕出,盡量使用它。MAXFAST 的設(shè)置违帆,對(duì)于調(diào)用很多次 malloc 工作的函數(shù)由很大的性能提升浙巫;
將編譯器優(yōu)化選項(xiàng)打開(kāi)!K⒑蟆的畴!