我听说在发布模式下编译会生成优化代码而不是调试模式,这很好。
但这是IL的优化吗?一旦CLR运行它,它在机器代码中吗?是不同于在Release和Debug中编译的PE的元数据结构?
感谢
答案 0 :(得分:14)
在Release版本中构建将打开C#编译器的/ optimize编译选项。这有很少的副作用,IL确实会改变但不是很多。值得注意的是,编译器不再努力使代码完全可调试。例如,它跳过一个空的静态构造函数,它不再发出NOP操作码,允许您在花括号上设置断点,并允许具有不同范围的局部变量在堆栈帧中重叠。小东西。
最重要的区别是为程序集发出的[Debuggable]属性,其IsJITOptimizerDisabled属性为false。
打开了真正的优化器,它是内置于抖动中的优化器。您将在this answer中找到它执行的优化列表。请注意这种方法的有用性,任何语言都可以从抖动而不是编译器中获得代码优化器。
简而言之,IL中的微小变化,生成的机器代码中的非常大的变化。
答案 1 :(得分:3)
是的,在IL中有一些优化 - 特别是,调试版本将包含NOP指令,这使得调试器可以轻松插入断点,我相信。在提供的调试信息的级别(行号等)方面也存在潜在的差异。
我建议您采用一个小示例程序,以两种方式编译它,然后查看ildasm
中的输出。
C#编译器不执行很多优化 - JIT编译器完成了大部分工作 - 但我认为存在一些差异。
答案 2 :(得分:1)
cil不同,它是优化的。由于机器代码是cil的翻译,它也有所不同。您可以自己查看,只需打开visual studio中的反汇编窗口即可。元数据应保持不变,因为您不会更改版本之间的类合同结构。
答案 3 :(得分:0)
在VB中,编辑到可执行文件中的编辑+继续支持有副作用,这可能导致内存泄漏。它受使用WithEvents关键字声明的任何事件的影响。 WeakReference会跟踪这些事件实例。问题是,如果您在没有调试器的情况下运行应用程序,那些WeakReferences会泄露。进程占用内存的速率在很大程度上取决于创建类的实例数。每个对象的每个事件泄漏16个字节。
免责声明:复制自Hans的回答here
答案 4 :(得分:0)
这不是确切问题的答案。只是要补充一点,你可以有目的地标记哪些代码必须在调试模式下运行,哪些代码在发布模式下借助预处理器标记。
#if DEBUG
// code only meant for debug mode
#endif
#if NOT DEBUG
// code only meant for release mode
#endif
因此,如果你这样做,你会得到不同的IL。