visual-studio Visual Studio 应用程序在调试时运行速度极慢
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3362895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Visual Studio application running extremely slow with debug
提问by plaisthos
I have a native C++ program which runs more than 20 times slower when started with Debug(F5), but runs at normal speed when using start without debug (Ctrl+ F5).
我有一个本机 C++ 程序,它在使用Debug( F5)启动时运行速度慢了 20 多倍,但在使用 start without debug ( Ctrl+ F5)时以正常速度运行。
It does not matter whether I use a debug or release build. Also if I use WinDbg the program is a magnitude slower.
我使用调试版本还是发布版本都没有关系。此外,如果我使用 WinDbg,程序会慢很多。
Is there some setting I did choose wrong or something?
是否有一些设置我确实选择了错误或什么?
采纳答案by Calvin1602
Set the _NO_DEBUG_HEAP environment variable to 1 (as seen on http://preshing.com/20110717/the-windows-heap-is-slow-when-launched-from-the-debugger).
将 _NO_DEBUG_HEAP 环境变量设置为 1(如http://preshing.com/20110717/the-windows-heap-is-slow-when-launched-from-the-debugger 所示)。
This can be done from inside Visual Studio, too.
这也可以从 Visual Studio 内部完成。
Now this is just a workaround, and I'm curious to know how to refactor a program which suffers from this kind of problem. Do you have many std::map's, shared_ptr, or any other big indirections by any chance?
现在这只是一种解决方法,我很想知道如何重构遭受此类问题的程序。您是否有很多 std::map、shared_ptr 或任何其他大的间接访问?
回答by Hans Passant
This is of course not caused by having the _DEBUG symbol defined or compiling the code in the debug configuration. The added debugging code runs whether or not the debugger is attached to the program.
这当然不是由在调试配置中定义了 _DEBUG 符号或编译代码引起的。无论调试器是否附加到程序,添加的调试代码都会运行。
The debugger doesn't normally affect code execution, it stays out of the way by calling WaitForDebugEvent. Which blocks it, until the operating system tells it that something noteworthy happened. That can trigger a bunch of code in the debugger that can slow down your program. You can see the events listed in the DEBUG_EVENT structure documentation.
调试器通常不会影响代码执行,它通过调用 WaitForDebugEvent 来避开。它会阻止它,直到操作系统告诉它发生了值得注意的事情。这可能会触发调试器中的一堆代码,从而减慢您的程序速度。您可以看到 DEBUG_EVENT 结构文档中列出的事件。
Annotating them a bit beyond the documentation: the debugger steps in and can slow down your program when:
在文档之外对它们进行注释:调试器会介入并在以下情况下减慢您的程序:
The program loads or unloads a DLL. Lots of stuff happens during load, the debugger goes hunting for a debug symbol file (.pdb). It may contact a symbol server to download it. Any breakpoints that were set in the DLL source code will get activated. This can be quite slow, but the effect is temporary and generally only slows down the startup. You can see the load/unload notification in the Output window.
The program raises an exception. This activates the debugger at the moment the exception is raised, a "first chance notification". Which can be very helpful, you can use the Debug + Exception, Thrown checkbox to make the debugger stop when the exception is raised. You can see the notification message in the Output window. This doesslow down code that raises and catches exceptions tremendously and is quite likely the source of your slowdown. Never use exceptions for flow control.
A thread starts running or terminates. Again, a notification message is printed to the Output window. You'd have to create a lotof threads to make this slow down your program.
When your program uses OutputDebugString() for tracing purposes. Visible in the Output window. Another good candidate for a slow down, output falls in the bit bucket if no debugger is attached. You shouldn't have any trouble diagnosing this as the cause, the obvious side-effect is seeing a lotof messages in the Output window.
When the program hits a breakpoint. Not a lot of reasons to be stumped by that one. But you can set breakpoints that slow down the program a lot yet don't cause a debugger break. Particularly the Conditional breakpoint, Hit counter, Filter and the When Hit operation will be slow. Use Debug + Windows + Breakpoints to review the breakpoints that are defined.
该程序加载或卸载一个 DLL。加载期间会发生很多事情,调试器会寻找调试符号文件 (.pdb)。它可能会联系符号服务器来下载它。在 DLL 源代码中设置的任何断点都将被激活。这可能会很慢,但效果是暂时的,通常只会减慢启动速度。您可以在“输出”窗口中看到加载/卸载通知。
程序引发异常。这会在引发异常时激活调试器,即“第一次机会通知”。这非常有用,您可以使用 Debug + Exception, Thrown 复选框使调试器在引发异常时停止。您可以在“输出”窗口中看到通知消息。这确实会减慢引发和捕获异常的代码的速度,并且很可能是导致速度减慢的根源。永远不要使用异常进行流量控制。
线程开始运行或终止。同样,通知消息会打印到“输出”窗口。您必须创建大量线程才能使程序变慢。
当您的程序使用 OutputDebugString() 进行跟踪时。在输出窗口中可见。如果没有附加调试器,则另一个减速的好候选者,输出将落在位桶中。您应该可以轻松地将其诊断为原因,明显的副作用是在“输出”窗口中看到大量消息。
当程序遇到断点时。没有太多理由被那个难倒。但是您可以设置断点来大大减慢程序的速度,但不会导致调试器中断。特别是条件断点、命中计数器、过滤器和命中时操作会很慢。使用 Debug + Windows + Breakpoints 查看定义的断点。
回答by Chiel ten Brinke
For me the difference in performance between debug mode and release mode is about a factor 40. After some digging, it appears several things contribute to the difference in performance, but there is one compiler option that quadruplesmy debug performance almost for free.
对我来说,调试模式和发布模式之间的性能差异大约是40倍。经过一番挖掘,似乎有几件事导致了性能差异,但有一个编译器选项几乎免费使我的调试性能翻了两番。
Namely, changing /ZIinto /Zi. For a description, see the MSDN page.
即,/ZI变成/Zi. 有关说明,请参阅MSDN 页面。
I don't use the edit and continuefeature anyway.
无论如何,我不使用编辑并继续功能。
回答by crokusek
No one has mentioned closing unused source windows.
没有人提到关闭未使用的源窗口。
After closing 20+ unused windows, debug source stepping went from ~5s back down to ~.2s. This unusually slow project loads a DLL dynamically and that DLL was also the one being stepped through (and having source windows open) so it seems likely related. However this was C# (headline and tags are non-specific).
关闭 20 多个未使用的窗口后,调试源步进从 ~5s 回落到 ~.2s。这个异常缓慢的项目会动态加载一个 DLL,并且该 DLL 也是正在逐步执行的项目(并打开源窗口),因此它似乎是相关的。然而,这是 C#(标题和标签是非特定的)。
回答by Merav Kochavi
When a process is created under the debugger, the operating system by default uses the debug heap. The debug heap does more verification of your memory, especially at de-alloc.
在调试器下创建进程时,操作系统默认使用调试堆。调试堆会对您的内存进行更多验证,尤其是在 de-alloc 时。
There are several possible options in order to disable the use of the Debug Heap:
有几种可能的选项可以禁用调试堆的使用:
Attach to the process soon after startup.This will allow you to speed up performance in debug mode knowingly so and being fully aware of the mode in which you are running.
Add the environment variable setting _NO_DEBUG_HEAP=1.
This can be set either globally for the machine or for a specific instance of Visual Studio.a. Globally you would set an environment variable through the Control Panel → System → Advanced system settings → Environment Variables, and there add the variable _NO_DEBUG_HEAP=1.
Note: This will have an affect on EVERY application you debug.b. For an instance of Visual Studio you can open a command prompt, setting the environment variable _NO_DEBUG_HEAP=1 and then open visual studio from inside that command prompt. This will influence only the processes created from that instance of Visual Studio will inherit the environment variable.
Append the behavior of the debugger, this is possible for VS2015. There are 2 ways to override this:
a. To modify for a specific project, go to the project properties Configuration Properties → Debugging and change the Environment property _NO_DEBUG_HEAP to 1
b. To modify for every project in Visual Studio, go to Tools → Options → Debugging and check the option: “Enable Windows debug heap allocator (Native only)”.
Note: f the _NO_DEBUG_HEAP environment variable mentioned in the 'a' is set in a project level it will override this global setting.
启动后立即附加到进程。这将使您能够在有意识的情况下提高调试模式下的性能,并完全了解您正在运行的模式。
添加环境变量设置_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 调试堆分配器(仅限本机)”。
注意:如果“a”中提到的 _NO_DEBUG_HEAP 环境变量是在项目级别设置的,它将覆盖此全局设置。
回答by the_mandrill
There are several things that are different if you run the debug build outside the IDE. One is that the IDE takes a while to load symbols, and if you depend on a lot of libraries then that startup time can be significant.
如果您在 IDE 之外运行调试版本,则有几件事会有所不同。一个是 IDE 需要一段时间来加载符号,如果您依赖很多库,那么启动时间可能很长。
If you are using a symbol server (including the Microsoft public symbol server) then this may add to the startup time, so ensure you have a local symbol cache in your _NT_SYMBOL_PATHvariable if that is the case.
如果您使用的是符号服务器(包括 Microsoft 公共符号服务器),那么这可能会增加启动时间,因此_NT_SYMBOL_PATH如果是这种情况,请确保您的变量中有本地符号缓存。
Also the IDE runs with the debug heap enabled, but I don't think this happens if you run outside the IDE.
此外,IDE 在启用调试堆的情况下运行,但我认为如果您在 IDE 之外运行,则不会发生这种情况。
回答by Matt Joiner
Debugging Visual C++ comes with lots and lots of overhead, especially in the STL. Try not defining _DEBUG, and define NDEBUG.
调试 Visual C++ 会带来很多开销,尤其是在 STL 中。尽量不定义_DEBUG,而定义NDEBUG。

