Is compiling Release and Debug going to generate different IL code + different machine code?

不打扰是莪最后的温柔 提交于 2019-11-30 03:03:49

问题


I heard compiling in Release mode generates optimized code than in Debug mode, which is fine.

But is this optimization in the IL? is it in the machine code once the CLR runs it? is the metadata structure different from PE compiled in Release and Debug?

thanks


回答1:


Building in Release build turns on the /optimize compile option for the C# compiler. That has a few side-effects, the IL indeed changes but not a great deal. Notable is that the compiler no longer makes an effort to make the code perfectly debuggable. It for example skips an empty static constructor, it no longer emits the NOP opcodes that allows you to set a breakpoint on a curly brace and allows local variables with different scopes to overlap in a stack frame. Small stuff.

The most important difference is the [Debuggable] attribute that's emitted for the assembly, its IsJITOptimizerDisabled property is false.

Which turns on the real optimizer, the one that's built into the jitter. You'll find the list of optimizations it performs in this answer. Do note the usefulness of this approach, any language benefits from having the code optimizer in the jitter instead of the compiler.

So in a nutshell, very minor changes in the IL, very large changes in the generated machine code.




回答2:


Yes, there's some optimization in the IL - in particular, the debug version will include NOP instructions which make it easy for a debugger to insert break points, I believe. There are also potentially differences in terms of the level of debug information provided (line numbers etc).

I suggest you take a small sample program, compile it in both ways, and then look at the output in ildasm.

The C# compiler doesn't do much optimization - the JIT compiler does most of that - but I think there are some differences.




回答3:


The cil differs, it is optimized. Since the machine code is a translation of the cil, it also differs. You can see it by yourself, just open the disassembly window in visual studio. Metadata should remain the same as you don't change the structure of class contracts between releases.




回答4:


In VB there is a side-effect of Edit + Continue support compiled into the executable, which can cause a memory leak. It is affected by any event that is declared with the WithEvents keyword. A WeakReference keeps track of those event instances. Problem is, those WeakReferences are leaked if you run the app without a debugger. The rate at which the process consumes memory is highly dependent on how many instances of the class get created. The leak is 16 bytes per event per object.

Disclaimer: copied from Hans' answer here

See this Microsoft knowledge base article.




回答5:


This is not an answer to the exact question. Just to add that you can purposefully mark which code has to be run in debug mode and which in release mode with the help of preprocessor markups.

 #if DEBUG
    // code only meant for debug mode
 #endif

 #if NOT DEBUG
    // code only meant for release mode
 #endif

So if you do this you'd get different IL generated.



来源:https://stackoverflow.com/questions/13751929/is-compiling-release-and-debug-going-to-generate-different-il-code-different-m

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!