C#的调试模式与发布模式

12

一个 Windows 服务在 debug build 和 release build 中性能有多大提升(如果有的话),为什么会有这个提升?


这是一个非常好的问题,如果有人能提供一些基准度量标准,那将会很有帮助。 - kbrimington
可能是C#调试与发布性能的重复问题。 - Michael Burr
2个回答

6
对于托管代码而言,除非你在DEBUG版本中有很多条件编译的内容,否则差异应该很小——IL代码应该基本相同。Jitter在调试器下运行和不运行时生成的代码不同,但对IL的编译影响不大。
在编译为IL时,/optimize会做一些事情,但它们并不是特别激进的优化。其中一些IL优化可能会被Jitter优化处理,即使在IL中没有进行优化(比如删除nops)。
详见Eric Lippert的文章http://blogs.msdn.com/ericlippert/archive/2009/06/11/what-does-the-optimize-switch-do.aspx

/optimize标志不会改变我们发出和生成逻辑的大部分。我们尝试始终生成直接、可验证的代码,然后依赖于Jitter在生成真正的机器代码时完成大量优化工作。但如果设置了该标志,我们将执行一些简单的优化。

阅读Eric的文章,了解/optimize在IL生成方面的不同之处。

好东西...那安全呢?如果你发布/暴露了调试信息,检查会不会揭示更多关于你的代码?即使性能差异微不足道,除非必须,否则我不会发布调试代码。 - Edward Leno
1
@Edward:我并不是在主张分发DEBUG构建版本,只是说你可能不应该期望DEBUG和RELEASE构建版本之间有很大的性能差异。此外,我认为DEBUG构建版本本身汇编中没有更多的细节 - 调试信息存储在.pdb文件中,你不需要分发它。.NET程序集通常很容易被反汇编/反编译(参见Reflector工具)。如果你关心反向工程,有混淆工具可以帮助解决这个问题,但我对它们并不了解。 - Michael Burr
1
谢谢...我忘记了.pdb文件包含调试信息。很多混淆工具并不是百分之百可靠,而且可能很昂贵。我总是认为如果有人真的想进去,他们就会进去。我应该花更多时间创新,少花时间保护。 - Edward Leno
@Edward:对于“花更多时间创新,少花时间保护”的建议点赞。保护代码的唯一真正方法是永远不让用户拥有它,例如只将其作为服务运行。如果用户拥有您的代码,他们可以将其反汇编。但他们很少这样做;使用法律防御而不是技术防御。 - Donal Fellows

1

虽然这个问题是重复的,但我觉得原问题中一些更好的答案在最底部。个人经历过在调试模式和发布模式下有明显差异的情况。(例如:Property performance,在访问属性时,在调试模式和发布模式之间存在2倍的差异)。无论这种差异是否存在于实际软件(而不是基准测试程序)中还有待商榷,但我曾经在一个产品上看到过它发生。

从Neil在原问题上的回答,来自msdn social

它没有被很好地记录,这是我知道的。编译器会发射一个System.Diagnostics.DebuggableAttribute的实例。在调试版本中,IsJitOptimizerEnabled属性为True,在发布版本中为False。你可以在程序集清单中使用ildasm.exe查看此特性。
JIT编译器使用该特性禁用会使调试变得困难的优化,如循环不变提升等移动代码的优化。在某些情况下,这可能会对性能产生很大影响,但通常并不会。
将断点映射到执行地址是调试器的工作。它使用.pdb文件和JIT编译器生成的信息,提供IL指令到代码地址的映射。如果您要编写自己的调试器,您会使用ICorDebugCode::GetILToNativeMapping()。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接