1. switch-case與if-else
switch-case的效率比if-else的效率要高很多袱吆,屬于典型的空間換時(shí)間問題歌径。在編譯的時(shí)候衣迷,會(huì)創(chuàng)建一個(gè)jump map存在于.rodata段中仍律,運(yùn)行的時(shí)候直接根據(jù)case值查表暇咆,找到對應(yīng)的值谤牡,直接跳轉(zhuǎn)到對應(yīng)的地址副硅。if-else需要遍歷條件分支直到命中條件。
1. 1switch—case的優(yōu)缺點(diǎn)
(1)switch case的優(yōu)點(diǎn):
????當(dāng)分支較多時(shí)翅萤,用switch的效率是很高的恐疲。因?yàn)閟witch是確定了選擇值之后直接跳轉(zhuǎn)到那個(gè)特定的分支.
(2)witch case的缺點(diǎn):
1.switch...case占用較多的代碼空間,因?yàn)樗?b>跳表套么,特別是當(dāng)case常量分布范圍很大但實(shí)際有效值又比較少的情況培己,switch...case的空間利用率將變得很低。
2.switch...case只能處理case為常量的情況胚泌。一般為字符常量或者數(shù)字類型的變量省咨,局限性比較大。
1.2. if-else的優(yōu)缺點(diǎn)
(1)if else的優(yōu)點(diǎn):if else能應(yīng)用于更多的場景玷室,更加靈活零蓉。
(2)if else的缺點(diǎn):if else必須遍歷所以得可能值,執(zhí)行效率比較低穷缤。
2. 指針問題
從上面的例子可以看出敌蜂,A和B的效率是不能比的。在同樣的存儲(chǔ)空間下津肛,B直接使用指針就可以操作了章喉,而A需要調(diào)用兩個(gè)字符函數(shù)才能完成。B的缺點(diǎn)在于靈活性沒有A好快耿。在需要頻繁更改一個(gè)字符串內(nèi)容的時(shí)候囊陡,A具有更好的靈活性;如果采用方法B掀亥,則需要預(yù)存許多字符串撞反,雖然占用了大量的內(nèi)存,但是獲得了程序執(zhí)行的高效率搪花。如果系統(tǒng)的實(shí)時(shí)性要求很高遏片,內(nèi)存還有一些嘹害,那我推薦你使用該招數(shù)。
總結(jié):核心思想其實(shí)是將需要用到的信息事先定義好吮便,在使用的時(shí)候直接調(diào)用即可笔呀,字符串的賦值、數(shù)值的計(jì)算(查表)等等髓需。
3. 宏和函數(shù)
方法1:
#define bwMCDR2_ADDRESS 4
#define bsMCDR2_ADDRESS 17
int BIT_MASK(int __bf){
? ? return ((1U << (bw ## __bf)) - 1) << (bs ## __bf);
}
void SET_BITS(int __dst, int __bf, int __val){
? ? __dst = ((__dst) & ~(BIT_MASK(__bf))) | \(((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))
}
SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);
方法2:
#define bwMCDR2_ADDRESS 4
#define bsMCDR2_ADDRESS 17
#define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)
#define BIT_MASK(__bf) (((1U << (bw ## __bf)) - 1) << (bs ## __bf))
#define SET_BITS(__dst, __bf, __val) \
((__dst) = ((__dst) & ~(BIT_MASK(__bf))) | \
(((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))
SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);
函數(shù)和宏函數(shù)的區(qū)別就在于许师,宏函數(shù)占用了大量的空間,而函數(shù)占用了時(shí)間僚匆。大家要知道的是微渠,函數(shù)調(diào)用是要使用系統(tǒng)的棧來保存數(shù)據(jù)的,如果編譯器里有棧檢查選項(xiàng)咧擂,一般在函數(shù)的頭會(huì)嵌入一些匯編語句對當(dāng)前棧進(jìn)行檢查逞盆;同時(shí),CPU也要在函數(shù)調(diào)用時(shí)保存和恢復(fù)當(dāng)前的現(xiàn)場松申,進(jìn)行壓棧和彈棧操作云芦,所以,函數(shù)調(diào)用需要一些CPU時(shí)間贸桶。而宏函數(shù)不存在這個(gè)問題舅逸。宏函數(shù)僅僅作為預(yù)先寫好的代碼嵌入到當(dāng)前程序,不會(huì)產(chǎn)生函數(shù)調(diào)用刨啸,所以僅僅是占用了空間堡赔,在頻繁調(diào)用同一個(gè)宏函數(shù)的時(shí)候,該現(xiàn)象尤其突出设联。 方法2是我看到的最好的置位操作函數(shù)善已,是ARM公司源碼的一部分,在短短的三行內(nèi)實(shí)現(xiàn)了很多功能离例,幾乎涵蓋了所有的位操作功能换团。方法1是其變體,其中滋味還需大家仔細(xì)體會(huì)宫蛆。
引申:
注意inline和define的區(qū)別
4 內(nèi)聯(lián)函數(shù)
內(nèi)聯(lián)是C++對函數(shù)的一種特殊修飾艘包,實(shí)際上,內(nèi)聯(lián)函數(shù)可以更形象地被稱為內(nèi)嵌函數(shù)耀盗。當(dāng)編譯器編譯程序時(shí)想虎,如果發(fā)現(xiàn)某段代碼調(diào)用的是一個(gè)內(nèi)聯(lián)函數(shù),那么它就不再去調(diào)用該函數(shù)叛拷,而是將該函數(shù)的代碼直接插入當(dāng)前函數(shù)調(diào)用的位置舌厨,這樣就省去了函數(shù)調(diào)用過程中的那些繁瑣的幕后工作,提高了代碼的執(zhí)行效率忿薇,這樣就以程序空間的增加換取了執(zhí)行時(shí)間的減少裙椭。
內(nèi)聯(lián)函數(shù)的使用規(guī)則
1. 內(nèi)聯(lián)函數(shù)要短小精悍
內(nèi)聯(lián)函數(shù)的實(shí)質(zhì)是將函數(shù)代碼復(fù)制到函數(shù)調(diào)用的位置躏哩, 它的使用會(huì)增加程序的體積,所以內(nèi)聯(lián)函數(shù)應(yīng)該盡量做到短小精悍揉燃,一般不要超過5行扫尺。如果將一個(gè)比較復(fù)雜的函數(shù)內(nèi)聯(lián),往往會(huì)導(dǎo)致程序的體積迅速膨脹炊汤,最后往往得不償失正驻。
2. 內(nèi)聯(lián)函數(shù)執(zhí)行的時(shí)間要短
內(nèi)聯(lián)函數(shù)不僅要短小,同時(shí)其執(zhí)行時(shí)間也要短婿崭,這樣才能體現(xiàn)內(nèi)聯(lián)函數(shù)的優(yōu)勢拨拓。如果函數(shù)執(zhí)行的時(shí)間遠(yuǎn)大于函數(shù)調(diào)用過程中那些幕后工作所花費(fèi)的時(shí)間肴颊,那么通過內(nèi)聯(lián)函數(shù)所節(jié)省下來的那一點(diǎn)點(diǎn)時(shí)間也就無足輕重了氓栈。
3. 內(nèi)聯(lián)函數(shù)應(yīng)該是被重復(fù)多次調(diào)用的
內(nèi)聯(lián)函數(shù)每次調(diào)用節(jié)省下來的時(shí)間其實(shí)非常微小,只有當(dāng)這些時(shí)間累積到一定程度后婿着,它才具有實(shí)際的意義授瘦。如果一個(gè)內(nèi)聯(lián)函數(shù)只被調(diào)用過一次,那么它節(jié)省下來的那一點(diǎn)點(diǎn)時(shí)間是沒有任何實(shí)際意義的竟宋,反倒是因?yàn)閮?nèi)聯(lián)函數(shù)而增加了程序的體積提完。
4. ?inline關(guān)鍵字僅僅是一種建議
inline關(guān)鍵字僅僅是一種對編譯器的建議,表明程序員對這個(gè)函數(shù)的處理意見丘侠。但是在某些特定的情況下徒欣,編譯器將不理會(huì)inline關(guān)鍵字,而強(qiáng)制讓函數(shù)成為普通函數(shù)蜗字。這時(shí)編譯器會(huì)給出相應(yīng)的警告消息打肝。反過來,如果某個(gè)函數(shù)并沒有加上inline修飾挪捕,但如果編譯器在進(jìn)行代碼優(yōu)化的時(shí)候粗梭,認(rèn)為將這個(gè)函數(shù)內(nèi)聯(lián)會(huì)提高代碼性能,也會(huì)自作主張地將其內(nèi)聯(lián)级零。所以断医,inline關(guān)鍵字只是表示我們建議編譯器將函數(shù)內(nèi)聯(lián)處理,至于到底是否進(jìn)行內(nèi)聯(lián)處理奏纪,最終還是要看編譯器的臉色鉴嗤。
雖然內(nèi)聯(lián)函數(shù)可以在一定程度上提高應(yīng)用程序的性能,但是它并不是解決性能問題的靈丹妙藥序调,也并不是用得越多越好醉锅。很多時(shí)候,如果發(fā)現(xiàn)應(yīng)用程序存在性能上的問題炕置,更多地應(yīng)該從應(yīng)用程序的結(jié)構(gòu)和設(shè)計(jì)上尋找問題的解決辦法荣挨。內(nèi)聯(lián)函數(shù)男韧,只是飯前的小甜點(diǎn)而已,偶爾嘗一點(diǎn)還不錯(cuò)默垄,但是并不能當(dāng)飯吃此虑。
表達(dá)式形式的宏定義一例:
#define?ExpressionName(Var1,Var2) ????(Var1+Var2)*(Var1-Var2)
inline 推出的目的,也正是為了取代這種表達(dá)式形式的宏定義口锭,它消除了它的缺點(diǎn)朦前,同時(shí)又很好地繼承了它的優(yōu)點(diǎn)。inline代碼放入預(yù)編譯器符號(hào)表中鹃操,高效韭寸;它是個(gè)真正的函數(shù),調(diào)用時(shí)有嚴(yán)格的參數(shù)檢測荆隘;它也可作為類的成員函數(shù)恩伺。
#define 宏名要替換的代碼????
宏定義巾钉,保存在預(yù)編譯器的符號(hào)表中牵啦,執(zhí)行高效吗冤;作為一種簡單的符號(hào)替換柬甥,不進(jìn)行其中參數(shù)有效性的檢測
typedef 已有類型 新類型
別名, 常用于創(chuàng)建平臺(tái)無關(guān)類型, typedef 在編譯時(shí)被解釋凰锡,因此讓編譯器來應(yīng)付超越預(yù)處理器能力的文本替換