如何優化程式效能

2021-09-02 17:45:22 字數 2338 閱讀 5332

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-0hr3d09z-1610031215959)(深入理解計算機系統/優化程式效能/達克效應.jpg)]

這篇筆記主要是摘抄了具體的**示例,從**中體會如何優化程式的效能,《深入理解計算機系統》已經看了近三分之二了,越看越發現自己懂得太少太少了,正在題圖中的絕望之谷徘徊(我自認為是這樣),至少比在愚昧山峰左邊的山腳徘徊要好很多。

我們的編譯器已經提供了很好的優化機制,但是還有很多細節編譯器優化不到,或者說沒膽量去優化,因為有一些激進的優化很有可能會違背程式設計師的初心。

// 第一種

void

twiddle1

(long

*xp,

long

*yp)

// 第二種

void

twiddle2

(long

*xp,

long

*yp)

例如上面的程式,看到第一種寫法,我們可能很容易的就想到第二種寫法,但是編譯器卻不會把它變成這種寫法。乍看它們沒什麼區別,我們來分析一下記憶體引用。第一種需要 3 次記憶體引用,即讀\*xp、讀\*yp、寫\*xp;而第二種卻需要 6 次記憶體引用,即2 次讀\*xp、2 次讀\*yp、2 次寫\*xp。所以第一種的效能要比第二種好。

那編譯器看到第一種為什麼就想不到第二種寫法呢?這不是很簡單的規則嗎?實際上上面的程式存在xp = yp的情況,即兩個指標指向同乙個記憶體位置。

// 第一種

*xp +

=*yp;

// xp 處存放的值乘以 2

*xp +

=*yp;

// xp 處存放的值乘以 2

// 第二種

*xp +=2

**yp;

// xp 處存放的值乘以 3

可以看到,當它們都指向同一塊記憶體時,第一種寫法會讓原來的值增加 4 倍,而第二種寫法會讓原來的值增加 3 倍,產生了不同的效果,而編譯器會當這種情況可能出現,所以編譯器並不會幫我們優化第一種**,這需要程式設計師自己去維護。

消除迴圈的低效率

相信很多人都寫過下面類似的**,貌似沒有什麼可以優化的,寫的挺好。

void

lower1

(char

*s)}

}

仔細看,會發現每次迴圈都會去呼叫strlen()函式,而這個函式明顯是要拖累效能的,實際上我們只需要計算一次長度就可以了,現在卻每次迴圈都需要去計算一次長度,所以可以將計算移到前面只計算一次的地方。

void

lower2

(char

*s)}

}

編譯器雖然會試著去進行**的移動,但是最終還是沒有優化,是因為改變在**呼叫函式或者呼叫多少次函式的變換,編譯器並不能比較可靠的發現乙個函式是否有***,比如下面的情況。

longf(

);long

func1()

long

func2()

這段**和開篇提到的**在形式上很像,可能你會說:它們不會指到同一塊記憶體了呀,編譯器這也不去優化嗎?考慮一下f()是下面的形式。

long count =0;

longf(

)

是不是一下就發現問題了,func1()呼叫 4 次f(),而func2()只呼叫 1 次f(),它們最終的結果絕不是簡單的 4 倍關係。

編寫適合條件傳送實現的**

如果編譯器能夠產生使用條件資料傳送而不是條件控制轉移的**,那麼就可以大大的提高程式的效能,關於條件資料傳送和條件控制轉移在舊文順序、條件、迴圈語句的底層解釋中描述的已經很明確了。比如下面的第一種寫法就比第二種要好。

// 第一種

void

minmax1

(long a,

long b,

long n)}}

// 第二種

void

minmax2

(long a,

long b,

long n)

}

暫時就寫這幾個吧,還有個消除不必要的記憶體引用,因為它的效能問題不能從**中直接看出來,就不放出來了,工作中盡自己所能寫出優雅的**。

優化程式效能

編寫高效程式需要兩個活動 第一,我們必須選擇一組最好的演算法和資料結構 第二,我們必須編寫出編譯器能夠有效優化以轉換成高效可執行 的源 這裡,我們主要講述後者。首先,我們討論一下為什麼要編寫高效程式。不難想象,如果本來要用 天執行完的程式,經過優化只需要 天就可執行完,這是一件多麼令人振奮的 事啊。...

優化程式效能

l 消除迴圈的低效率 n 對於迴圈中的過程呼叫盡量移出迴圈外,例如 nfor i 0 i strlen s i strlen 函式為線性增長 在字串長度很大時 很消耗系統資源 n 減少不必要的儲存器引用,將儲存器引用儲存在臨時變數中.l 處理器優化 即充分利用儲存器流水線操作的吞吐量 n 迴圈展開,...

優化程式效能

研究彙編 是理解編譯器以及產生的 會如何執行的最有效的手段之一。編譯器優化 的限制 1 程式設計中存在 儲存器別名使用 的問題。編譯器必須假設不同的指標可能指向儲存器中相同的位置。2 函式呼叫 簡略了。具體看書 基本的編碼原則 效能大幅度提公升 優化程式效能的一些方法 1 將除錯完的程式完成編譯器級...