天天看點

一個小的程式設計技巧,你知道嗎?

        今天看linux檔案系統的代碼,有一個小地方引起了我的注意。記在這裡,跟大家分享下。

       大體上是這樣子的(示例代碼如下)。一個函數接受一個const char*參數,然後在函數體内又配置設定了一個局部的const char *指針,并将剛才傳入的參數付給它,然後依次去通路(準确的講是讀取)其指向的字元串中的每個字元。當時我就懷疑為什麼還要申請一個局部變量呢?這不是更加浪費記憶體麼?直接用傳入的實參不是可以達到同樣的目的麼?

示例代碼:

    void foo(const char *str){

        const char *temp = str;

        while(*temp++){

...............

        }

................

        但後來一想,覺得這樣可能更友善編譯器去做優化(因為采用局部變量,其實是給編譯器的一種暗示,讓他把該變量放到寄存器中去)。推測歸推測,還是得驗證一下。打開vi,寫測試代碼,gcc編譯,并用objdump -d 檢視反彙編,定位到函數<foo>,發現果然如我所料。

        在不采用任何優化選項的情況下:

        1:如果不使用temp變量,如下面所示,你會發現編譯器生成的代碼中,每次循環會把ebp+0x10位址處的内容加1,然後取其内容并用間接尋址。

    void foo(const char *str){

        while(*str++){

...............

        }

................

        2:如果使用temp變量,則編譯器會把temp變量優化寄存器中,且每次循環都會隻增加寄存器中的值并按照寄存器間接尋址來通路每個字元。

        可見,使用局部變量,确實有助于編譯器進行優化。

        不過,我們也不能低估了我們編譯器的能力。現在的編譯器跟以前相比,智能了很多,能夠做很多優化。比如還是上面的例子,如果不使用temp變量,但是隻要打開gcc的O2優化選項,編譯器便會自動的将變量優化到寄存器中去。

        總結一下:此處雖然用-O2也可以達優化的效果,但是如果程式稍微大起來,編譯的時間消耗還是很“可觀”的。本文提到的這個問題雖然看似很小,甚至有人可能會覺得不可一提,但我覺得任何一個嚴肅的程式員應該都不會一笑了之。這裡展現了計算機體系結構中一個非常重要的思想——局部性原理,沒有它,我甚至不敢想象現在的計算機會是什麼樣子。好了,再扯就遠了,到此為止,希望本文對大家有點幫助。

BTW:水準有限,歡迎拍磚^_^

轉載請注明轉自:http://blog.csdn.net/qingheuestc。

繼續閱讀