C#內聯函數 特性 MethodImplOptions.AggressiveInlining)


[MethodImpl(MethodImplOptions.AggressiveInlining)] 內聯函數

Impl:implement的縮寫

內聯函數

計算機科學中,內聯函數(有時稱作在線函數編譯時期展開函數)是一種編程語言結構,用來建議編譯器對一些特殊函數進行內聯擴展(有時稱作在線擴展);也就是說建議編譯器將指定的函數體插入並取代每一處調用該函數的地方(上下文),從而節省了每次調用函數帶來的額外時間開支。但在選擇使用內聯函數時,必須在程序占用空間和程序執行效率之間進行權衡,因為過多的比較復雜的函數進行內聯擴展將帶來很大的存儲資源開支。另外還需要特別注意的是對遞歸函數的內聯擴展可能引起部分編譯器的無窮編譯。

設計內聯函數的動機

內聯擴展是一種特別的用於消除調用函數時所造成的固有的時間消耗方法。一般用於能夠快速執行的函數,因為在這種情況下函數調用的時間消耗顯得更為突出。這種方法對於很小的函數也有空間上的益處,並且它也使得一些其他的優化成為可能。

沒有了內聯函式,程式員難以控制哪些函數內聯哪些不內聯;由編譯器自行決定是否內聯。加上這種控制維度准許特定於應用的知識,諸如執行函式的頻繁程度,被利用於選擇哪些函數要內聯。

此外,在一些語言中,內聯函數與編譯模型聯系緊密:如在C++中,有必要在每個使用它的模塊中定義一個內聯函數;與之相對應的,普通函數必須定義在單個模塊中。這使得模塊編譯獨立於其他的模塊。

只有C++ C 才有內聯函數關鍵字,因為C++/c注重運行效率。 C#中沒有提供內聯關鍵字,不過在在.NET4.5中開始提供了  內聯函數ethodImplOptions.aggressiveinline特性, 提示/建議1CLR允許使用M值方法內聯 。例如:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int GetCurrentProcessorId() { ///其他代碼 }

引入內聯函數的目的

函數是一種更高級的抽象。它的引入使得編程者只關心函數的功能和使用方法,而不必關心函數功能的具體實現;函數的引入可以減少程序的目標代碼,實現程序代碼和數據的共享。但是,函數調用也會帶來降低效率的問題,因為調用函數實際上將程序執行順序轉移到函數所存放在內存中某個地址,將函數的程序內容執行完后,再返回到轉去執行該函數前的地方。這種轉移操作要求在轉去前要保護現場並記憶執行的地址,轉回后先要恢復現場,並按原來保存地址繼續執行。因此,函數調用要有一定的時間和空間方面的開銷,於是將影響其效率。特別是對於一些函數體代碼不是很大,但又頻繁地被調用的函數來講,解決其效率問題更為重要。引入內聯函數實際上就是為了解決這一問題。

使用函數內聯的條件:

 雖然C#不支持inline關鍵字,但是JIT支持自動inline,即將IL轉成真正機器碼時,會自動將某些函數進行inline展開,只是條件非常苛刻,網上提到JIT自動進行inline展開的一些選擇依據:

1)函數內部有循環語句、catch語句等復雜結構,都不做inline優化。
2)函數體比較長的不做inline優化,只有比較簡單的才可能inline優化。(有人說IL不足32字節才做inline),
3)編譯成機器碼時,inline展開的代碼比函數調用更短的,一定做inline。(注:如果參數多而代碼少,就符合此情況)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM