使用附加到进程的CLR调试器,.NET代码运行速度会变慢吗?

时间:2010-08-12 22:58:03

标签: c# .net debugging

标题所说的几乎是:我正在运行一个很长的程序,它附加了CLR调试器,所以我可以捕获并检查异常。我的性能是否与在没有调试器的情况下运行它相当,或者是否存在严重(2-10倍或更多)的惩罚?

3 个答案:

答案 0 :(得分:7)

重要人物:工具+选项,调试,常规,模块负载的抑制JIT优化。如果你想调试发布代码并获得可比较的性能,你希望这样做。但是,这会使调试代码变得更加困难,JIT优化器会将局部变量存储在CPU寄存器中(Watch将无法工作)并重新排序和内联代码(步进行为很奇怪)。

然后是DebuggableAttribute,由编译器自动生成。它的IsJITOptimizerEnabled和IsJITTrackingEnabled属性很重要。首先,他们努力使局部变量保持活动只需要比所需更长的时间,防止垃圾收集器收集您可能希望在调试器中检查的引用。容易避免,只需调试Release版本而不是Debug版本。

然后在您的程序中发生特定的事情,唤醒调试器并使其窃取CPU周期:

  • 当您的程序抛出异常时。调试器在抛出之前会对其进行一次射击。称为“第一次机会通知”,您可以在“输出”窗口中看到它。这就是Debug + Exceptions对话框的工作原理。大大减慢了异常处理速度。
  • 当您的程序加载或卸载DLL时。很多东西都发生在加载时,调试器试图找到DLL的符号。检查是否需要激活任何断点。并在“输出”窗口中显示通知。这通常只会使程序启动变慢,尤其是在打开混合模式调试时。
  • 将Trace类与DefaultTraceListener,Debug.Write / Line()方法或Console.Write / Line一起使用,并启用托管进程。输出显示在“输出”窗口中,会大大减慢这些调用。
  • 当程序中的某个线程启动或停止时。在“输出”窗口中可见。让它减慢你的程序将是一个设计错误。

就是这样,只要不执行上面列出的操作,调试器就会停止运行并让代码全速运行。 ASP.NET和Silverlight等运行时环境很特殊,可能还有额外的开销。在64位操作系统上调试Any CPU程序也是如此,这需要远程调试器,因为VS仅为32位。

答案 1 :(得分:5)

我看到了相当大的差异,是的。

特别是,当抛出异常时,在附加调试器时,它们会更长批次。还有一些其他重要的优化可能会影响行为 - 例如,当未附加调试器时,垃圾收集器很多更具攻击性。

为什么不记录异常而不是破解调试器?除了其他任何东西,这意味着如果你想回去查看昨天发生的异常并将其与刚刚发生的异常进行比较,这很容易......回到过去很难:)

答案 2 :(得分:2)

附加调试器会禁用一些JIT优化 - 例如函数内联。

http://msdn.microsoft.com/en-us/library/bb384548.aspx

你的表现可能会更糟。