简体   繁体   中英

Visual Studio application running extremely slow with debug

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 ).

It does not matter whether I use a debug or release build. Also if I use WinDbg the program is a magnitude slower.

Is there some setting I did choose wrong or something?

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 ).

This can be done from inside Visual Studio, too.

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?

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.

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.

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 does slow 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 lot of 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 lot of 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.

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.

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_PATH variable if that is the case.

Also the IDE runs with the debug heap enabled, but I don't think this happens if you run outside the IDE.

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.

There are several possible options in order to disable the use of the Debug Heap:

  1. 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.

  2. 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.

  3. 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.

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 quadruples my debug performance almost for free.

Namely, changing /ZI into /Zi . For a description, see the MSDN page .

I don't use the edit and continue feature anyway.

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).

Debugging Visual C++ comes with lots and lots of overhead, especially in the STL. Try not defining _DEBUG , and define NDEBUG .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM