我有一个本机C ++程序,当使用 Debug ( F5 )启动时运行速度慢20多倍,但在使用start而不调试时运行速度正常(< kbd> Ctrl + F5 )。
使用调试版本还是发布版本并不重要。此外,如果我使用WinDbg,程序的速度会慢一些。
是否有一些设置我选择了错误或什么?
答案 0 :(得分:16)
将_NO_DEBUG_HEAP环境变量设置为1(如http://preshing.com/20110717/the-windows-heap-is-slow-when-launched-from-the-debugger所示)。
这也可以在Visual Studio内部完成。
现在这只是一种解决方法,我很想知道如何重构一个遭受这类问题的程序。你有很多std :: map's,shared_ptr或任何其他大的间接吗?
答案 1 :(得分:12)
这当然不是因为在调试配置中定义了_DEBUG符号或编译代码。无论调试器是否附加到程序,都会运行添加的调试代码。
调试器通常不会影响代码执行,它通过调用WaitForDebugEvent而不会停止。阻止它,直到操作系统告诉它发生了一些值得注意的事情。这可能会在调试器中触发一堆代码,从而降低程序速度。您可以看到DEBUG_EVENT结构文档中列出的事件。
将它们注释到文档之外:调试器介入并在以下情况下降低程序速度:
程序加载或卸载DLL。在加载过程中会发生很多事情,调试器会寻找调试符号文件(.pdb)。它可能会联系符号服务器下载它。 DLL源代码中设置的任何断点都将被激活。这可能非常慢,但效果是暂时的,通常只会减慢启动速度。您可以在“输出”窗口中看到加载/卸载通知。
该程序引发异常。这会在引发异常时激活调试器,即“第一次机会通知”。这可能非常有用,您可以使用Debug + Exception,Thrown复选框使调试器在引发异常时停止。您可以在“输出”窗口中看到通知消息。这个会减慢代码,这会极大地提升和捕获异常,很可能是您放缓的源头。切勿使用异常进行流量控制。
线程开始运行或终止。同样,通知消息将打印到“输出”窗口。你必须创建一个 lot 的线程来减慢你的程序。
当您的程序使用OutputDebugString()进行跟踪时。在“输出”窗口中可见。如果没有附加调试器,那么减速的另一个好选择是输出落在位桶中。你应该没有任何问题将其诊断为原因,明显的副作用是在输出窗口中看到批次消息。
当程序遇到断点时。没有太多理由被那个难倒。但是你可以设置断点来减慢程序的速度但不会导致调试器中断。特别是条件断点,命中计数器,过滤器和命中时操作都会很慢。使用Debug + Windows + Breakpoints查看已定义的断点。
答案 2 :(得分:1)
如果在IDE外部运行调试版本,则有一些不同之处。一个是IDE需要一段时间来加载符号,如果你依赖很多库,那么启动时间可能很大。
如果您使用的是符号服务器(包括Microsoft公共符号服务器),那么这可能会增加启动时间,因此如果是这种情况,请确保在_NT_SYMBOL_PATH
变量中有本地符号缓存。 / p>
此外,IDE在启用调试堆的情况下运行,但如果您在IDE外部运行,我认为不会发生这种情况。
答案 3 :(得分:1)
在调试器下创建进程时,操作系统默认使用调试堆。调试堆会对内存进行更多验证,尤其是在解除分配时。
有几种可能的选项可以禁用Debug Heap:
启动后不久就会附加到进程。这样可以让您在调试模式下有效地加快性能,并充分了解您运行的模式。
添加环境变量设置_NO_DEBUG_HEAP = 1。
这可以为机器或Visual Studio的特定实例全局设置。一个。在全局范围内,您可以通过控制面板→系统→高级系统设置→环境变量设置环境变量,然后添加变量_NO_DEBUG_HEAP = 1。 注意:这将对您调试的每个应用程序产生影响。
湾对于Visual Studio的实例,您可以打开命令提示符,设置环境变量_NO_DEBUG_HEAP = 1,然后从该命令提示符中打开visual studio。这将仅影响从中创建的进程 Visual Studio的实例将继承环境 变量
- 醇>
附加调试器的行为,VS2015可以这样做。有两种方法可以覆盖它:
一个。要修改特定项目,请转到项目属性Configuration Properties→Debugging并将Environment属性_NO_DEBUG_HEAP更改为1
湾要修改Visual Studio中的每个项目,请转到工具→选项→调试,然后选中选项:“启用Windows调试堆分配器(仅限本机)”。
注意:f&#39; a&#39;中提到的_NO_DEBUG_HEAP环境变量。在项目级别设置它将覆盖此全局设置。
答案 4 :(得分:1)
对我来说,调试模式和发布模式之间的性能差异大约是 40 。经过一番挖掘后,似乎有几个因素导致性能上的差异,但有一个编译器选项四倍我的调试性能几乎是免费的。
即,将/ZI
更改为/Zi
。有关说明,请参阅the MSDN page。
我还是不使用编辑并继续功能。
答案 5 :(得分:0)
调试Visual C ++会带来大量的开销,特别是在STL中。不要定义_DEBUG
,并定义NDEBUG
。
答案 6 :(得分:0)
没有人提到关闭未使用的源窗口。
关闭了20多个未使用的窗口后,调试源步进从~5s回到〜.2s。这个异常缓慢的项目动态加载DLL,并且DLL也是正在逐步执行的(并且源窗口打开),因此它似乎可能相关。然而,这是C#(标题和标签是非特定的)。