编译器评估显式null-check与null-coalescing运算符?

Rob*_*Rob 4 c# compiler-construction clr cil compiler-theory

请考虑以下代码,该代码使用两种略有不同的方法来检查_instance并在尚未设置时分配它.

class InstantiationTest
{
    private Object _instance;

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

    public void Method2() {
        _instance = _instance ?? new Object();
    }
}
Run Code Online (Sandbox Code Playgroud)

VS或Resharper不断为我的显式空检查加下划线,并提示我使用null-coalescing运算符进行重构.

我不知道该编译器是否足够聪明来检测的情况下Method2()在那里_instance被重新分配给自己(实际上是一个NOP?),并改写Method2()Method1().

我看到实际情况并非如此:

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   
Run Code Online (Sandbox Code Playgroud)

与:

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      
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么

在编译器级别实现是否棘手,是否值得实现的努力是微不足道的,或者我缺少的东西?

the*_*oop 5

通常,C#编译器对IL的优化很少,只能将其归结为JIT,这可以为特定体系结构更好地优化.所以它根本没有在编译器中实现,因为这需要时间远离其他事情.

  • 有可能.但是,如果你担心这种差异对性能的影响,那就是"微优化"阵营,你应该去担心其他事情! (2认同)