2. 空間換時間問題

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)付超越預處理器能力的文本替換

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容