返回变量是由编译器自动创建的吗?

时间:2014-06-26 08:51:47

标签: c# compiler-construction

当查看项目源代码时,我偶然发现了一个方法并且想知道一件事。从性能/内存/编译器的角度来看,以下两种方法是否完全相同?

public static string Foo(string inputVar)
{
    string bar = DoSomething(inputVar);
    return bar;
}

public static string Foo(string inputVar)
{
    return DoSomething(inputVar);
}

返回变量是否由编译器自动创建?

1 个答案:

答案 0 :(得分:8)

使用 IL反汇编程序(包含在.NET SDK / VS中),您可以查看编译器生成的IL。代码是使用VS2013(而不是Roslyn)生成的。

最上面一个给出以下IL:

.method public hidebysig static string  Foo(string inputVar) cil managed
{
  // Code size       14 (0xe)
  .maxstack  1
  .locals init ([0] string bar,
           [1] string CS$1$0000)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  call       string TestIL.Program::DoSomething(string)
  IL_0007:  stloc.0
  IL_0008:  ldloc.0
  IL_0009:  stloc.1
  IL_000a:  br.s       IL_000c
  IL_000c:  ldloc.1
  IL_000d:  ret
} // end of method Program::Foo

第二个:

.method public hidebysig static string  Foo(string inputVar) cil managed
{
  // Code size       12 (0xc)
  .maxstack  1
  .locals init ([0] string CS$1$0000)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  call       string TestIL.Program::DoSomething(string)
  IL_0007:  stloc.0
  IL_0008:  br.s       IL_000a
  IL_000a:  ldloc.0
  IL_000b:  ret
} // end of method Program::Foo

差异似乎是第一个在方法locals表中创建了一个额外的条目。如果这是由JIT编译器优化的,我不知道。

回答这个问题:不,在这种情况下编译器似乎不会自动生成局部变量,但在更高级的情况下它可能会这样做(如返回x *(y + z))。

编辑:如果您打开“优化代码”,则更加清晰:

.method public hidebysig static string  Foo(string inputVar) cil managed
{
  // Code size       9 (0x9)
  .maxstack  1
  .locals init ([0] string bar)
  IL_0000:  ldarg.0
  IL_0001:  call       string TestIL.Program::DoSomething(string)
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ret
} // end of method Program::Foo

.method public hidebysig static string  Foo(string inputVar) cil managed
{
  // Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       string TestIL.Program::DoSomething(string)
  IL_0006:  ret
} // end of method Program::Foo