简体   繁体   中英

Huge performance impact between VS2005 debug mode and release mode

I had an issue that a Win32 application has huge performance difference between debug and release build. It takes 20 sec for release, while 6 min for debug build to initialize the application. This is painful since when debugging, it always takes 6 min to proceed the initialization before starting doing anything. So I am looking for a way to tune the performance in debug build.

After running profiler, I found below code is the hot-spot.

class CellList {
    std::vector<CellPtr>* _cells;
    iterator begin() { return (*_cells).begin(); }
    iterator end()   { return (*_cells).end(); }
    reverse_iterator rbegin() { return (*_cells).rbegin(); }
    reverse_iterator rend()   { return (*_cells).rend(); }
    ...
}

CellList _cellList = ...;

for (CellList::iterator itr = _cellList.begin(), end = _cellList.end(); itr < end; ++itr) {
  Cell* cell = *itr;
  if (cell->getFoo()) cell->setBar(true);
  else cell->setBar(false);
}

for (CellList::iterator itr = _cellList.rbegin(), end = _cellList.rend(); itr < end; ++itr) {
  Cell* cell = *itr;
  if (cell->getFoo2()) cell->setBar2(true);
  else cell->setBar2(false);
}

And these are the hot-spot in the time-base profile result.

std::operator< <std::_Vector_iterator<Cell *,std::allocator<Cell *> >,std::_Vector_iterator<Cell *,std::allocator<Cell *> > >
std::_Vector_const_iterator<Cell *,std::allocator<Cell *> >::operator<
std::reverse_iterator<std::_Vector_iterator<Cell *,std::allocator<Cell *> > >::operator*
std::reverse_iterator<std::_Vector_const_iterator<Cell *,std::allocator<Cell *> > >::reverse_iterator<std::_Vector_const_iterator<Cell *,std::allocator<Cell *> > ><std::_Vector_iterator<Cell *,std::allocator<Cell *> > >

I guess it's the iterator operation not being inlined and causes this huge difference. Is there any way to improve this? I can debug in release mode as long as it's still possible to step line by line in the source code and check all the variable values.

The difference is normal. What'd I'd do is place

#pragma optimize("",off)

#pragma optimize("",on)

around the methods you want to check, and keep the rest of the build in release mode.

6 minutes vs. 20 seconds is a ratio of 18:1 (call it 20:1 for simplicity).

That means the debug version is spending 95% of its time doing something extra that the release version is not.

OK, run it under the debugger. Hit the pause button and look at the call stack. Chances are 19/20 that you will see what is taking the extra time. Do it a few times to be sure.

When I did this, it was doing class validation methods, which are turned off in release mode. Often it was re-validating the same data, by different paths, over and over.

In your case, it might well be those iterators. If you're not doing much else, they can easily be dominant.

But don't guess.

One problem is that the "fast debug checks" which are on by default in VC++ debug builds will slow your code down by up to a factor of five. They occasionally find bugs, but not often enough to justify the cost you are seeing. See my blog post for more details:

Visual C++ Debug Builds–”Fast Checks” Cause 5x Slowdowns

Turn them off and every little function gets noticeably faster.

If your slowdown is only on initialization INSIDE the debugger (but not if you run the Debug build as a regular application), it is caused by Visual Studio loading debug symbols for all libraries that you are using. This is expected, but you can fine-tune which symbols get loaded from the debugging preferences.

Lack of optimizations will of course slow things in general, but not specifically on startup inside the debugger.

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