1. switch-case與if-else
switch-case的效率比if-else的效率要高很多,屬于典型的空間換時間問題。在編譯的時候,會創(chuàng)建一個jump map存在于.rodata段中,運行的時候直接根據(jù)case值查表,找到對應(yīng)的值,直接跳轉(zhuǎn)到對應(yīng)的地址。if-else需要遍歷條件分支直到命中條件。
1. 1switch—case的優(yōu)缺點
(1)switch case的優(yōu)點:
????當分支較多時,用switch的效率是很高的。因為switch是確定了選擇值之后直接跳轉(zhuǎn)到那個特定的分支.
(2)witch case的缺點:
1.switch...case占用較多的代碼空間,因為它要生成跳表,特別是當case常量分布范圍很大但實際有效值又比較少的情況,switch...case的空間利用率將變得很低。
2.switch...case只能處理case為常量的情況。一般為字符常量或者數(shù)字類型的變量,局限性比較大。
1.2. if-else的優(yōu)缺點
(1)if else的優(yōu)點:if else能應(yīng)用于更多的場景,更加靈活。
(2)if else的缺點:if else必須遍歷所以得可能值,執(zhí)行效率比較低。
2. 指針問題

從上面的例子可以看出,A和B的效率是不能比的。在同樣的存儲空間下,B直接使用指針就可以操作了,而A需要調(diào)用兩個字符函數(shù)才能完成。B的缺點在于靈活性沒有A好。在需要頻繁更改一個字符串內(nèi)容的時候,A具有更好的靈活性;如果采用方法B,則需要預存許多字符串,雖然占用了大量的內(nèi)存,但是獲得了程序執(zhí)行的高效率。如果系統(tǒng)的實時性要求很高,內(nèi)存還有一些,那我推薦你使用該招數(shù)。
總結(jié):核心思想其實是將需要用到的信息事先定義好,在使用的時候直接調(diào)用即可,字符串的賦值、數(shù)值的計算(查表)等等。
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ù)調(diào)用是要使用系統(tǒng)的棧來保存數(shù)據(jù)的,如果編譯器里有棧檢查選項,一般在函數(shù)的頭會嵌入一些匯編語句對當前棧進行檢查;同時,CPU也要在函數(shù)調(diào)用時保存和恢復當前的現(xiàn)場,進行壓棧和彈棧操作,所以,函數(shù)調(diào)用需要一些CPU時間。而宏函數(shù)不存在這個問題。宏函數(shù)僅僅作為預先寫好的代碼嵌入到當前程序,不會產(chǎn)生函數(shù)調(diào)用,所以僅僅是占用了空間,在頻繁調(diào)用同一個宏函數(shù)的時候,該現(xiàn)象尤其突出。 方法2是我看到的最好的置位操作函數(shù),是ARM公司源碼的一部分,在短短的三行內(nèi)實現(xiàn)了很多功能,幾乎涵蓋了所有的位操作功能。方法1是其變體,其中滋味還需大家仔細體會。
引申:
注意inline和define的區(qū)別
4 內(nèi)聯(lián)函數(shù)
內(nèi)聯(lián)是C++對函數(shù)的一種特殊修飾,實際上,內(nèi)聯(lián)函數(shù)可以更形象地被稱為內(nèi)嵌函數(shù)。當編譯器編譯程序時,如果發(fā)現(xiàn)某段代碼調(diào)用的是一個內(nèi)聯(lián)函數(shù),那么它就不再去調(diào)用該函數(shù),而是將該函數(shù)的代碼直接插入當前函數(shù)調(diào)用的位置,這樣就省去了函數(shù)調(diào)用過程中的那些繁瑣的幕后工作,提高了代碼的執(zhí)行效率,這樣就以程序空間的增加換取了執(zhí)行時間的減少。
內(nèi)聯(lián)函數(shù)的使用規(guī)則
1. 內(nèi)聯(lián)函數(shù)要短小精悍
內(nèi)聯(lián)函數(shù)的實質(zhì)是將函數(shù)代碼復制到函數(shù)調(diào)用的位置, 它的使用會增加程序的體積,所以內(nèi)聯(lián)函數(shù)應(yīng)該盡量做到短小精悍,一般不要超過5行。如果將一個比較復雜的函數(shù)內(nèi)聯(lián),往往會導致程序的體積迅速膨脹,最后往往得不償失。
2. 內(nèi)聯(lián)函數(shù)執(zhí)行的時間要短
內(nèi)聯(lián)函數(shù)不僅要短小,同時其執(zhí)行時間也要短,這樣才能體現(xiàn)內(nèi)聯(lián)函數(shù)的優(yōu)勢。如果函數(shù)執(zhí)行的時間遠大于函數(shù)調(diào)用過程中那些幕后工作所花費的時間,那么通過內(nèi)聯(lián)函數(shù)所節(jié)省下來的那一點點時間也就無足輕重了。
3. 內(nèi)聯(lián)函數(shù)應(yīng)該是被重復多次調(diào)用的
內(nèi)聯(lián)函數(shù)每次調(diào)用節(jié)省下來的時間其實非常微小,只有當這些時間累積到一定程度后,它才具有實際的意義。如果一個內(nèi)聯(lián)函數(shù)只被調(diào)用過一次,那么它節(jié)省下來的那一點點時間是沒有任何實際意義的,反倒是因為內(nèi)聯(lián)函數(shù)而增加了程序的體積。
4. ?inline關(guān)鍵字僅僅是一種建議
inline關(guān)鍵字僅僅是一種對編譯器的建議,表明程序員對這個函數(shù)的處理意見。但是在某些特定的情況下,編譯器將不理會inline關(guān)鍵字,而強制讓函數(shù)成為普通函數(shù)。這時編譯器會給出相應(yīng)的警告消息。反過來,如果某個函數(shù)并沒有加上inline修飾,但如果編譯器在進行代碼優(yōu)化的時候,認為將這個函數(shù)內(nèi)聯(lián)會提高代碼性能,也會自作主張地將其內(nèi)聯(lián)。所以,inline關(guān)鍵字只是表示我們建議編譯器將函數(shù)內(nèi)聯(lián)處理,至于到底是否進行內(nèi)聯(lián)處理,最終還是要看編譯器的臉色。
雖然內(nèi)聯(lián)函數(shù)可以在一定程度上提高應(yīng)用程序的性能,但是它并不是解決性能問題的靈丹妙藥,也并不是用得越多越好。很多時候,如果發(fā)現(xiàn)應(yīng)用程序存在性能上的問題,更多地應(yīng)該從應(yīng)用程序的結(jié)構(gòu)和設(shè)計上尋找問題的解決辦法。內(nèi)聯(lián)函數(shù),只是飯前的小甜點而已,偶爾嘗一點還不錯,但是并不能當飯吃。
表達式形式的宏定義一例:
#define?ExpressionName(Var1,Var2) ????(Var1+Var2)*(Var1-Var2)
inline 推出的目的,也正是為了取代這種表達式形式的宏定義,它消除了它的缺點,同時又很好地繼承了它的優(yōu)點。inline代碼放入預編譯器符號表中,高效;它是個真正的函數(shù),調(diào)用時有嚴格的參數(shù)檢測;它也可作為類的成員函數(shù)。
#define 宏名要替換的代碼????
宏定義,保存在預編譯器的符號表中,執(zhí)行高效;作為一種簡單的符號替換,不進行其中參數(shù)有效性的檢測
typedef 已有類型 新類型
別名, 常用于創(chuàng)建平臺無關(guān)類型, typedef 在編譯時被解釋,因此讓編譯器來應(yīng)付超越預處理器能力的文本替換