Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is return variable automatically created by compiler?

When going over the project source code, I stumbled upon a method and wondered about one thing. Are the following two methods EXACTLY same from the performance/memory/compiler point of view?

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

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

Is the return variable automatically created by compiler?

like image 632
anar khalilov Avatar asked Jun 26 '14 08:06

anar khalilov


1 Answers

Using IL Disassembler (included in the .NET SDK/VS) you can look at the IL generated by the compiler. The code is generated using VS2013 (not Roslyn).

The top one gives the following 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

The second one:

.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

The difference seems to be that the first one creates an extra entry in the methods locals table. If this is optimized away by the JIT compiler I don't know.

To answer the question: No, it doesn't seems that the compiler automatically generates a local variable in this case, but in more advanced case it might do (like return x * (y + z)).

Edit: If you turn on "Optimize code" its even more clear:

.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
like image 88
svenslaggare Avatar answered Oct 10 '22 07:10

svenslaggare