Search code examples
c#optimizationjitdisassembly

How can I simulate JIT optimized code and view the change?


I'm trying to check whether a while statement with empty block is being JIT optimized, so I try to run my code at release mode and view the code from Visual Studio's Debug->Windows->Disassembly window. However I'm not seeing any change from the compiled code. I tried to add some statements that I expect to be optimized:

  bool b = false;
    if (b)
                        {
                            new Object();
                        }

but I still see it on the disassembly window:

                        bool b = false;
                        if (b)
                        {
0524A8FF  mov         ecx,dword ptr [ebx+0Ch]  
0524A902  push        dword ptr ds:[33422A0h]  
0524A908  mov         edx,esi  
0524A90A  cmp         dword ptr [ecx],ecx  
0524A90C  call        71DE3490  
0524A911  test        eax,eax  
0524A913  je          0524A97C  
0524A915  mov         ecx,51DEAC4h  
0524A91A  call        002E30F4  
0524A91F  mov         edi,eax  
0524A921  lea         edx,[edi+8]  
0524A924  call        72D12410  
                            new Object();
                        }

I also tried with NGen tool that is mentioned on a related question, but I keep seeing my "junk code" (which I expected to be optimized away), maybe the problem is that I don't write a proper "junk code" that will be optimized away, if that's the case I'd be happy for some better example of code that the JIT should optimize.

How can I add some trivial code that will be optimized for sure and then verify in that disassembly window that the code I added is not there?


Solution

  • The snippet is not good enough to get a repro. Fleshing it out:

    class Program {
        static void Main(string[] args) {
            bool b = false;
            if (b) {
                new object();
            }
        }
     }
    

    Produces:

                bool b = false;
    02390450  ret  
    

    That is extreme optimization at work, none of the code survived. The jitter optimizer can tell that b is always false so it doesn't bother generating the constructor call. Dead code elimination is one of the optimization strategies.

    I tried to add some statements that I expect to be optimized

    That was the problem, you cannot see any side-effect of added statements that don't produce any code. All that is there is the machine code produced by the original code.

    Do beware that the source annotations that are visible in the Disassembly window are only accurate when you use the Debug build. In the optimized Release build they can get pretty bewildering wrong due to the optimizer moving and deleting code.