C語言高效程式設計的四大祕技之以空間換時間

無名_四葉草發表於2020-04-05

轉自:http://tech.163.com/06/1201/10/318HH45C00091KVA.html

引言:

編寫高效簡潔的C語言程式碼,是許多軟體工程師追求的目標。本文就工作中的一些體會和經驗做相關的闡述,不對的地方請各位指教。

第1招:以空間換時間

計算機程式中最大的矛盾是空間和時間的矛盾,那麼,從這個角度出發逆向思維來考慮程式的效率問題,我們就有了解決問題的第1招——以空間換時間。

例如:字串的賦值。

方法A,通常的辦法:

#define LEN 32
char string1 [LEN];

memset (string1,0,LEN);
strcpy (string1,“This is a example!!”);

方法B:

const char string2[LEN] =“This is a example!”;
char * cp;

cp = string2 ;//(使用的時候可以直接用指標來操作。)

從上面的例子可以看出,A和B的效率是不能比的。在同樣的儲存空間下,B直接使用指標就可以操作了,而A需要呼叫兩個字元函式才能完成。B的缺點在於靈活性沒有A好。在需要頻繁更改一個字串內容的時候,A具有更好的靈活性;如果採用方法B,則需要預存許多字串,雖然佔用了大量的記憶體,但是獲得了程式執行的高效率。

如果系統的實時性要求很高,記憶體還有一些,那我推薦你使用該招數。

該招數的變招——使用巨集函式而不是函式。舉例如下:

方法C:

#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);

方法D:

#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);

函式和巨集函式的區別就在於,巨集函式佔用了大量的空間,而函式佔用了時間。大家要知道的是,函式呼叫是要使用系統的棧來儲存資料的,如果編譯器裡有棧檢查選項,一般在函式的頭會嵌入一些彙編語句對當前棧進行檢查;同時,CPU也要在函式呼叫時儲存和恢復當前的現場,進行壓棧和彈棧操作,所以,函式呼叫需要一些CPU時間。而巨集函式不存在這個問題。巨集函式僅僅作為預先寫好的程式碼嵌入到當前程式,不會產生函式呼叫,所以僅僅是佔用了空間,在頻繁呼叫同一個巨集函式的時候,該現象尤其突出。 D方法是我看到的最好的置位操作函式,是ARM公司原始碼的一部分,在短短的三行內實現了很多功能,幾乎涵蓋了所有的位操作功能。C方法是其變體,其中滋味還需大家仔細體會。

相關文章