• 文章
  • 行內函數優點、缺點
釋出
2010 年 3 月 8 日 (最後更新:2011 年 9 月 28 日)

行內函數優點、缺點、效能和使用指南?

評分:3.6/5 (239 票)
*****
行內函數是編譯器使用的一種最佳化技術。只需在函式原型前加上 inline 關鍵字即可將函式宣告為行內函數。行內函數會指示編譯器將函式的完整主體插入到程式碼中任何呼叫該函式的地方。

優點: 1) 無需函式呼叫開銷。
2) 呼叫函式時,還可以節省棧上變數的壓棧/彈棧開銷。
3) 還可以節省函式返回的開銷。
4) 透過利用指令快取來提高引用區域性性。
5) 內聯後,編譯器還可以應用過程內最佳化(intraprocedural optimization),如果指定的話。這是最重要的一點,透過這種方式,編譯器可以專注於死程式碼消除、更側重於分支預測、歸納變數消除等。

缺點 :-
1) 可能會增加函式大小,導致其無法放入快取,引起大量快取未命中。
2) 行內函數後,如果將要使用暫存器的變數數量增加,可能會對暫存器變數資源利用造成開銷。
3) 可能會導致編譯開銷,因為如果有人更改行內函數中的程式碼,所有呼叫該函式的位置都將重新編譯。
4) 如果在標頭檔案中使用,會使標頭檔案變大,甚至難以閱讀。
5) 如果使用過多的行內函數導致程式碼量增大,可能會在記憶體中造成顛簸(thrashing)。越來越多的頁錯誤(page fault)會降低程式效能。
6) 對於不希望二進位制檔案過大的嵌入式系統,由於記憶體大小的限制,行內函數並不適用。

效能 : -
現在我們來討論大家最關心的話題——“效能”。
在大多數情況下,行內函數的使用可以提高效能,因為它節省了大量開銷,如我們在上面的優點部分所述。但正如我們也討論了其缺點一樣,在使用時需要非常小心。如今的現代編譯器會自動對行內函數進行最佳化,因此在大多數情況下無需顯式指定。雖然放置 inline 關鍵字只是給編譯器一個提示,表明該函式可以透過內聯進行最佳化,但最終是否內聯由編譯器決定。不過,也有一些方法可以指示編譯器進行內聯,例如在 Microsoft Visual C++ 中,可以使用 __forceinline 來指示編譯器行內函數。我建議除非您對效能提升非常有把握,否則不要使用此關鍵字。使函式內聯可能會也可能不會帶來效能提升,這完全取決於您的程式碼流程。不要指望透過在函式前加上 inline 關鍵字就能帶來神奇的效能提升,因為如今大多數編譯器都會自動執行此操作。

正如我們所見,行內函數在效能方面有所幫助,但必須非常謹慎地使用。

我準備了一些使用指南。
使用指南 :-
1) 當您確定它能提高效能時,請始終使用行內函數。
2) 始終優先使用行內函數而不是宏。
3) 不要內聯程式碼量大的函式,為了獲得性能,應該始終內聯程式碼量小的函式。
4) 如果要在類中行內函數,請優先在類外部定義函式時使用 inline 關鍵字。
5) 在 C++ 中,預設情況下,在類內宣告和定義的成員函式會被內聯。因此,在此類情況下無需指定。
6) 如果異常處理模型存在差異,函式將不會被內聯。例如,如果呼叫函式遵循 C++ 結構化處理,而您的行內函數遵循結構化異常處理。
7) 對於遞迴函式,大多數編譯器不會進行內聯,但 Microsoft Visual C++ 編譯器為此提供了一個特殊的 pragma:pragma inline_recursion(on),您還可以使用 pragma inline_depth 來控制其限制。
8) 如果函式是虛擬函式且以虛擬方式呼叫,則不會被內聯。因此,請注意這種情況,函式指標的使用也同樣如此。

有關更多此類資訊,請訪問我的技術部落格:
http://www.tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html
以上就是我的全部內容,希望您喜歡閱讀這篇帖子。