c# - .NET 代码是否随着 CLR 调试器附加到进程而运行得更慢?

标签 c# .net debugging

正如标题所言:我正在运行一个长程序,它附加了 CLR 调试器,因此我可以捕获和检查异常。我获得的性能是否与在没有调试器的情况下运行它相当,或者我是否付出了严重的(2-10 倍或更多)代价?

最佳答案

重点:工具 + 选项、调试、常规、抑制模块加载的 JIT 优化。如果您想调试发布代码并获得可比较的性能,则需要关闭它。然而,这确实会使调试代码变得更加困难,JIT 优化器会将局部变量存储在 CPU 寄存器中(Watch 将无法工作)并重新排序和内联代码(步进行为很奇怪)。

然后是编译器自动生成的 DebuggableAttribute。它的 IsJITOptimizerEnabled 和 IsJITTrackingEnabled 属性很重要。首先,它们致力于使局部变量保持事件状态的时间比必要的时间稍长一点,从而防止垃圾收集器收集您可能希望在调试器中检查的引用。很容易避免,只需调试发布版本而不是调试版本。

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

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

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

关于c# - .NET 代码是否随着 CLR 调试器附加到进程而运行得更慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3472671/

相关文章:

.net - UserControl Focus 问题 - Focus() 有时返回 false

c# - 重写 .NET 基类库中的现有功能

c++ - 进入子进程时gdb中断

android - 对于 Eclipse 和 Android,IDE 从不显示异常值

c# - Microsoft Bot Framework System.ArgumentException : 'EncryptedText is not properly formatted'

c# - 使用 MVVM 模式的 UI 设计

c# - 如何从 f# 返回一个空元组到 c#?

.net - 是否可以从 .NET 中的动态方法调用内部方法?

c++ - 我在哪里可以看到 mfc 应用程序中的 printf 输出?

c# - ReSharper:空检查始终是错误警告