简体   繁体   English

正在编译Release和Debug会生成不同的IL代码+不同的机器代码吗?

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

I heard compiling in Release mode generates optimized code than in Debug mode, which is fine. 我听说在Release模式下编译生成的优化代码比在Debug模式下生成,这很好。

But is this optimization in the IL? 但这是IL的优化吗? is it in the machine code once the CLR runs it? 一旦CLR运行它,它在机器代码中吗? is the metadata structure different from PE compiled in Release and Debug? 是否与在Release和Debug中编译的PE不同的元数据结构?

thanks 谢谢

Building in Release build turns on the /optimize compile option for the C# compiler. 在Release版本中构建将打开C#编译器的/ optimize编译选项。 That has a few side-effects, the IL indeed changes but not a great deal. 这有一些副作用,IL确实改变但不是很多。 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. 例如,它跳过一个空的静态构造函数,它不再发出NOP操作码,允许您在花括号上设置断点,并允许具有不同范围的局部变量在堆栈帧中重叠。 Small stuff. 小东西。

The most important difference is the [Debuggable] attribute that's emitted for the assembly, its IsJITOptimizerDisabled property is false. 最重要的区别是为程序集发出的[Debuggable]属性,其IsJITOptimizerDisabled属性为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. 因此简而言之,IL中的微小变化,生成的机器代码的变化非常大。

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. 是的,在IL中有一些优化 - 特别是,调试版本将包含NOP指令,这使得调试器可以轻松插入断点,我相信。 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 . 我建议你采用一个小的示例程序,以两种方式编译它,然后查看ildasm中的输出。

The C# compiler doesn't do much optimization - the JIT compiler does most of that - but I think there are some differences. C#编译器没有做太多优化--JIT编译器完成了大部分工作 - 但我认为存在一些差异。

The cil differs, it is optimized. cil不同,它是优化的。 Since the machine code is a translation of the cil, it also differs. 由于机器代码是cil的翻译,它也有所不同。 You can see it by yourself, just open the disassembly window in visual studio. 您可以自己查看,只需打开visual studio中的反汇编窗口即可。 Metadata should remain the same as you don't change the structure of class contracts between releases. 元数据应保持不变,因为您不会更改版本之间的类合同结构。

In VB there is a side-effect of Edit + Continue support compiled into the executable, which can cause a memory leak. 在VB中,编辑到可执行文件中的编辑+继续支持有副作用,这可能导致内存泄漏。 It is affected by any event that is declared with the WithEvents keyword. 它受使用WithEvents关键字声明的任何事件的影响。 A WeakReference keeps track of those event instances. WeakReference会跟踪这些事件实例。 Problem is, those WeakReferences are leaked if you run the app without a debugger. 问题是,如果您在没有调试器的情况下运行应用程序,那些WeakReferences会泄露。 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. 每个对象的每个事件泄漏16个字节。

Disclaimer: copied from Hans' answer here 免责声明:从汉斯的答案抄在这里

See this Microsoft knowledge base article . 请参阅此Microsoft知识库文章

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. 所以,如果你这样做,你会得到不同的IL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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