简体   繁体   中英

Poor quality compiler optimization in c#

I don't know why but I watched the IL generated from the standard c# compiler (VS2015) and it's dramatically non optimized in release mode.

The code that I tested is very simple:

static void Main(string[] args)
    {
        int count = 25 + 7/3;
        count += 100;
        Console.WriteLine("{0}", count);
    }

The IL output in debug mode is:

// [12 9 - 12 10]
IL_0000: nop          

// [34 13 - 34 34]
IL_0001: ldc.i4.s     27 // 0x1b
IL_0003: stloc.0      // count

// [35 13 - 35 26]
IL_0004: ldloc.0      // count
IL_0005: ldc.i4.s     100 // 0x64
IL_0007: add          
IL_0008: stloc.0      // count

// [36 13 - 36 45]
IL_0009: ldstr        "{0}"
IL_000e: ldloc.0      // count
IL_000f: box          [mscorlib]System.Int32
IL_0014: call         void [mscorlib]System.Console::WriteLine(string, object)
IL_0019: nop          

// [37 9 - 37 10]
IL_001a: ret          

and the code in Release mode is:

 IL_0000: ldc.i4.s     27 // 0x1b
IL_0002: stloc.0      // V_0
IL_0003: ldloc.0      // V_0
IL_0004: ldc.i4.s     100 // 0x64
IL_0006: add          
IL_0007: stloc.0      // V_0
IL_0008: ldstr        "{0}"
IL_000d: ldloc.0      // V_0
IL_000e: box          [mscorlib]System.Int32
IL_0013: call         void [mscorlib]System.Console::WriteLine(string, object)
IL_0018: ret  

Now, Why the compiler are not perform the sum (27 + 100) and direct call WriteLine with 127 ?

I tried the same sample in c++ and it works as expected.

There's some special flag to perform this kind optimization?

UPDATE: I try the same code on MONO 4.6.20 and the result in release mode is the following

 // method line 2
.method private static hidebysig
       default void Main (string[] args)  cil managed
{
    // Method begins at RVA 0x2058
    .entrypoint
    // Code size 18 (0x12)
    .maxstack 8
    IL_0000:  ldstr "{0}"
    IL_0005:  ldc.i4.s 0x7f
    IL_0007:  box [mscorlib]System.Int32
    IL_000c:  call void class [mscorlib]System.Console::WriteLine(string, ob                                                                                                                               ject)
    IL_0011:  ret
} // end of method Program::Main

You can't rely on the IL output of the compiler to accurately assess how optimized the code is, because the JIT is going to get its hand on the IL at runtime to generate the actual code to run. In this case the actual x64 emitted by the JIT (in Release mode for Any CPU without Prefer 32-bit) looks like this:

sub         rsp,28h  
mov         rcx,7FFF85323E98h  
call        00007FFF91C72530  ; I'm not sure what this call does, I assume it's allocating memory for the boxed int
mov         rcx,20CA5CB3648h  
mov         rcx,qword ptr [rcx]  ; After this rcx is actually pointing to the string "{0}"
mov         dword ptr [rax+8],7Fh ; Box the value 127 into the object that rax points at
mov         rdx,rax  
call        00007FFF85160070  ; Call Console.WriteLine with its arguments in rcx and rdx
nop  
add         rsp,28h  
ret  

So the extra edition gets elided.

If I turn on "Prefer 32-bit", the emitted x86 looks like this:

mov         ecx,72041638h  
call        011630F4  ; presumably allocating memory for the boxed int
mov         edx,eax  
mov         eax,dword ptr ds:[40E232Ch] ; loads a pointer to "{0}" into eax
mov         dword ptr [edx+4],7Fh  ; boxes 127 into object pointed at by edx
mov         ecx,eax  
call        71F373F4  ; calls Console.WriteLine with arguments in ecx and edx
ret  

In both cases the JIT optimized out the local variable as well as the extra addition operations. Since the JIT performs so many optimizations, you'll find that the C# compiler itself doesn't go to great lengths to optimize anything.

tl;dr The emitted IL from the C# compiler is not what the machine runs and so is not generally representative of the sorts of optimizations will be applied.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM