Visual Studio application running extremely slow with debug

17,681

Solution 1

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?

Solution 2

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.

Solution 3

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.

Solution 4

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.

Solution 5

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

Share:
17,681
plaisthos
Author by

plaisthos

a geek, handle with care

Updated on June 15, 2022

Comments

  • plaisthos
    plaisthos almost 2 years

    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?

  • the_mandrill
    the_mandrill almost 14 years
    That doesn't answer the OP's question though -- it's still a debug build, just running outside the IDE. The STL diagnostics will still run.
  • plaisthos
    plaisthos almost 14 years
    I am using the symbol server. But I am not speaking about the startup time but the time the program uses to actually run. I have diagnostic about with std::cout, which has about one per second with Ctrl+F5 and one evvery 30s or so when runing with F5. I think the heap debbuging depends on the _DEBUG macro which will do heap checking in both cases.
  • the_mandrill
    the_mandrill almost 14 years
    Do you have any conditional breakpoints or tracepoints set? These can slow execution down by an order of magnitude. Try disabling all breakpoints temporarily.
  • plaisthos
    plaisthos almost 14 years
    Unfortunally I do not have any such. Would have been too easy :)
  • the_mandrill
    the_mandrill almost 14 years
    What about any addins? Another thing to try is running Process Monitor to see if the devenv.exe process is accessing any files. I've found some cases where this happens a lot -- devenv keeps accessing my header files. Also try deleting the .suo file.
  • plaisthos
    plaisthos about 12 years
    I cannot confirm if this is really the case in my program but it really sounds like my problem.
  • plaisthos
    plaisthos about 10 years
    yeah stepping speed (ide ui speed) is something completely different than running an application
  • crokusek
    crokusek about 10 years
    I see, true that, hope it helps someone who was led here.
  • Ignacio Soler Garcia
    Ignacio Soler Garcia over 9 years
    Using Prism here so loading lots of modules after start-up. Seems to be the cause, yes.
  • huoneusto
    huoneusto over 3 years
    Loading of various DLL symbols seems to be the culprit lot of times. At least in my case it randomly makes the program run like on an ancient 286 (or even slower). Even simple printf()-grade statements take ages to complete. VS just doesn't show the "Loading..." dialog until after few minutes of execution, which then makes it obvious, why everything is so damn slow.