C#效率優化(2)-- 方法內聯

  1、JIT編譯器能夠經過將方法內聯展開(Method Inline Expansion)來提高效率,相似C++中的內聯函數(Inline Function),與C++的內聯函數不一樣的是,C#並不支持內聯函數,而是由JIT編譯器在運行時自動進行;ide

  1.對於虛方法,若是JIT編譯器能夠確認調用該方法時變量的運行時類型,支持方法內聯;若是不能夠確認變量的運行時類型,則不支持方法內聯;對於調用空虛方法,與支持方法內聯相比,不支持內聯用時約長5倍;
※包括虛屬性、虛索引器、虛事件都不支持方法內聯;
※抽象方法與虛方法在方法內聯方面基本一致;函數

  2.對於接口方法,若是使用該類型的變量調用,支持方法內聯;若是使用接口類型的變量調用,則不支持方法內聯;對於調用空接口方法,與使用類型的變量調用,使用接口的變量調用用時長約8倍:spa

public class MyBaseClass
{
    public virtual void MyFunc() { }
}
public interface IMyInterface
{
    void MyFunc();
}
public class MyClass : MyBaseClass, IMyInterface
{
    public override void MyFunc() { }
}
//使用時:
MyClass myClass = new MyClass();
MyBaseClass myBaseClass = new myBaseClass();
IMyInterface myInterface = myClass;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 1000000000; i++)
{
    myClass.MyFunc();
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds); //320
myBaseClass = myClass; //屢次賦值以使JIT編譯器沒法確認該變量的運行時類型
stopwatch.Restart();
for (int i = 0; i < 1000000000; i++)
{
    myBaseClass.MyFunc();
}
Console.WriteLine(stopwatch.ElapsedMilliseconds); //1600
stopwatch.Restart();
for (int i = 0; i < 1000000000; i++)
{
    myInterface.MyFunc();
}
Console.WriteLine(stopwatch.ElapsedMilliseconds); //2560

  2、其它不會內聯的狀況:pwa

  1.遞歸方法;
  2.包含循環語句的方法;
  3.包含異常處理的方法;
  4.方法體的IL代碼長度超過32字節的方法;
※能夠經過在方法聲明中加入命名空間System.Runtime.CompilerServices中的特性MethodImpl來忽略這個條件:code

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void MyFunc()
{
    //do…
}

 


若是您以爲閱讀本文對您有幫助,請點一下「推薦」按鈕,您的承認是我寫做的最大動力!blog

做者:Minotauros
出處:https://www.cnblogs.com/minotauros/遞歸

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。索引

相關文章
相關標籤/搜索