views:

617

answers:

8

We have a large C++ application, which sometimes we need to run as a debug build in order to investigate bugs. The debug build is much much slower than the release build, to the point of being almost unusable.

What tricks are available for making MSVC Debug builds execute faster without sacrificing too much on the debugability?

+2  A: 

profile the app and see what ti taking the time. you should then be able to see what debugging need to be tuned.

Preet Sangha
+1  A: 

Hi pauldoo,

there are several difference between debug builds and release builds that influence both debugability and speed. The most important are the _DEBUG/NDEBUG define, the compiler optimizations and the creation of debug information.

You might want to create a third Solution Configuration and play around with these settings. For example, adding debug information to a release build doesn't really decrease performance but you already get a sensible stack trace so you know which function you are in. Only the line information is not reliable because of the compiler optimizations.

If you want reliable line information, go on and turn off optimizations. This will slow down the execution a bit but this will still be faster than normal debug as long as the _DEBUG define is not set yet. Then you can do pretty good debugging, only everything that has "#ifdef _DEBUG" or similar around it won't be there (e.g. calls to assert etc.).

Hope this helps,

Jan

Jan
+3  A: 

Why don't you just switch on debug information in your release configuration?

demoncodemonkey
Debug info is already enabled in release. The problem is that many variables are unreadable in the debugger because of the aggressive optimization.
pauldoo
A: 

Which VS are you using? We moved from VS.net to VS2008 recently and I experienced same slowness while debugging on high end machine on > 500k LOC project. Turns out, Intellisense base got corrupted and would update itself constantly but get stuck somewhere. Deleting .ncb file solved the problem.

TheBlack
A: 

Are you using MFC?

In my experience, the main thing that can make a debug version slow is the class validation routines, which are usually disabled in release. If the data structure is at all tree-like, it can end up re-validating subtrees hundreds of times.

Regardless, if it is, say, 10 times slower than the release build, that means it is spending 1/10 of its time doing what's necessary, and 9/10 doing something else. If, while you're waiting for it, you just hit the "pause" button and look at the call stack, chances are 9/10 that you will see exactly what the problem is.

It's a quick & dirty, but effective way to find performance problems.

Mike Dunlavey
+2  A: 

We turned off Iterator debugging with the preprocessor symbols:

_HAS_ITERATOR_DEBUGGING=0
_SCL_SECURE=0

It helped a bit, but was still not as fast as we'd like. We also ended up making our debug build more release-like by defining NDEBUG instead of _DEBUG. There were a couple other options that we changed too, but I'm not remembering them.

Its unfortunate that we needed to do all this, but our application has a certain amount of work needed to be done every 50ms or its unusable. VS2008 out of the box would give us ~60ms times for debug and ~6ms times for release. With the tweaks mentioned above we could get debug down to ~20ms or so, which is at least usable.

MrSlippers
Just let it run flat out (i.e. continuously, not timer-triggered). That 10:1 debug:release slowdown you're seeing is just the kind of thing that is really easy to find with this technique:http://stackoverflow.com/questions/375913/what-can-i-use-to-profile-c-code-in-linux/378024#378024
Mike Dunlavey
... even at 20:6 slowdown, that means 70% of time is wasted. So if you take 10 samples, you will see the reason on the stack on 7 +/- 1.45 samples, and the stack will tell you why it's doing it, and it will be a poor reason, that you can find a work-around.
Mike Dunlavey
I actually ran a profiler on it. The problem was spread out to lots of methods and it looked like the function headers were eating up all the time not the body. I concluded this was due to extra checks visual studio was doing in debug mode.
MrSlippers
+1  A: 

Create a ReleaseWithSymbols configuration, that defines NDEBUG and has no optimisations enabled. This will give you better performance while maintaining accurate symbols for debugging.

0xC0DEFACE
+2  A: 

Use #pragma optimize("", off) at the top of selected files that you want to debug in release. This gives better stack trace/variable view.

Works well if it's only a few files you need to chase the bug in.

Marcus Lindblom
This is exactly the trick we later discovered and have now been using for a while. (I forgot to come back and update SO). The correct syntax is `#pragma optimize("", off)`, which can later be followed by a `#pragma optimize("", on)` to put the compiler back to normal, thus enabling this trick to be used on single functions at a time.
pauldoo
Thanks for pointing out the error. I've updated it.
Marcus Lindblom