2011-11-16 28 views
4

請考慮下面的代碼,它使用兩個稍微不同的方法來檢查_instance並在尚未設置時進行分配。編譯器評估顯式空檢查與空合併運算符?

class InstantiationTest 
{ 
    private Object _instance; 

    public void Method1() { 
     if(_instance == null) { 
      _instance = new Object(); 
     } 
    } 

    public void Method2() { 
     _instance = _instance ?? new Object(); 
    } 
} 

VS或Resharper不斷強調我的顯式空檢查,並提示我使用空合併運算符進行重構。

我不知道哪裏_instance重新分配給自己(實際上是nop?),並改寫Method2()Method1()編譯器是否足以檢測Method2()的情況下智能。

我認爲這是不實際的情況:

Test.Method1: 
IL_0000: ldarg.0  
IL_0001: ldfld  UserQuery+Test._instance 
IL_0006: brtrue.s IL_0013 
IL_0008: ldarg.0  
IL_0009: newobj  System.Object..ctor 
IL_000E: stfld  UserQuery+Test._instance 
IL_0013: ret 

與:

Test.Method2: 
IL_0000: ldarg.0  
IL_0001: ldarg.0  
IL_0002: ldfld  UserQuery+Test._instance 
IL_0007: dup   
IL_0008: brtrue.s IL_0010 
IL_000A: pop   
IL_000B: newobj  System.Object..ctor 
IL_0010: stfld  UserQuery+Test._instance 
IL_0015: ret  

我的問題是,爲什麼

難以在編譯器級實現,太微不足道,值得實現的努力,或我失蹤的東西?

回答

5

通常,C#編譯器對IL的優化很少,而將JIT留給JIT,JIT對特定體系結構優化得更好。所以這只是沒有在編譯器中實現,因爲這需要時間遠離其他事情。

+0

這很有道理,但您認爲這是通過JIT得到優化的東西嗎? – Rob

+2

可能。但是,如果您擔心這種差異會對性能造成影響,那就是「微型優化」陣營中的問題,您應該去擔心其他問題! – thecoop