#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector< vector<int> > dp(50000, vector<int>(4, -1));
cout << dp.size();
}
This tiny program takes a split second to execute when simply run from the command line. But when run in a debugger, it takes over 8 seconds. Pausing the debugger reveals that it is in the middle of destroying all those vectors. WTF?
Note - Visual Studio 2008 SP1, Core 2 Duo 6700 CPU with 2GB of RAM.
Added: To clarify, no, I'm not confusing Debug and Release builds. These results are on one and the same .exe, without even any recompiling inbetween. In fact, switching between Debug and Release builds changes nothing.
Running in the debugger changes the memory allocation library used to one that does a lot more checking. A program that does nothing but memory allocation and de-allocation is going to suffer much more than a "normal" program.
Edit Having just tried running your program under VS I get a call stack that looks like
ntdll.dll!_RtlpValidateHeapEntry@12() + 0x117 bytes
ntdll.dll!_RtlDebugFreeHeap@12() + 0x97 bytes
ntdll.dll!_RtlFreeHeapSlowly@12() + 0x228bf bytes
ntdll.dll!_RtlFreeHeap@12() + 0x17646 bytes
msvcr90d.dll!_free_base(void * pBlock=0x0061f6e8) Line 109 + 0x13 bytes
msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x0061f708, int nBlockUse=1)
msvcr90d.dll!_free_dbg(void * pUserData=0x0061f708, int nBlockUse=1)
msvcr90d.dll!operator delete(void * pUserData=0x0061f708)
desc.exe!std::allocator<int>::deallocate(int * _Ptr=0x0061f708, unsigned int __formal=4)
desc.exe!std::vector<int,std::allocator<int> >::_Tidy() Line 1134 C++
Which shows the debug functions in ntdll.dll and the C runtime being used.
Running a program with the debugger attached is always slower than without.
This must be caused by VS hooking into the new/delete calls and doing more checking when attached - or the runtime library uses IsDebuggerPresent API and does things different in that case.
You can easily try this from inside Visual Studio, start the program with Debug->Start Debugging or Debug->Start Without Debugging. Without debugging is like from command line, with exactly the same build configuration and executable.
The debug heap automatically gets enabled when you start your program in the debugger, as opposed to attaching to an already-running program with the debugger.
The book Advanced Windows Debugging by Mario Hewardt and Daniel Pravat has some decent information about the Windows heap, and it turns out that the chapter on heaps is up on the web site as a sample chapter.
Page 281 has a sidebar about "Attaching Versus Starting the Process Under the Debugger":
When starting the process under the debugger, the heap manager modifies all requests to create new heaps and change the heap creation flags to enable debug-friendly heaps (unless the _NO_DEBUG_HEAP environment variable is set to 1). In comparison, attaching to an already-running process, the heaps in the process have already been created using default heap creation flags and will not have the debug-friendly flags set (unless explicitly set by the application).
(Also: a semi-related question, where I posted part of this answer before.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With