我遇到一个问题,即Win32应用程序在调试版本和发布版本之间存在巨大的性能差异。发布需要20秒,而调试版本需要6分钟来初始化应用程序。这很痛苦,因为在调试时,在开始执行任何操作之前,始终需要6分钟才能进行初始化。所以我正在寻找一种方法来调整调试版本中的性能。
运行profiler后,我发现下面的代码是热点。
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);
}
这些是时基档案结果的热点。
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 *> > >
我猜这是迭代器操作没有内联并导致这个巨大的差异。有没有办法改善这个?我可以在发布模式下进行调试,只要它仍然可以在源代码中逐行执行并检查所有变量值。
答案 0 :(得分:3)
差异是正常的。我要做的是放置
#pragma optimize("",off)
#pragma optimize("",on)
围绕要检查的方法,并将其余部分保留在发布模式中。
答案 1 :(得分:2)
6分钟与20秒的比例为18:1(为简单起见称之为20:1)。
这意味着调试版本花费95%的时间做一些额外的发布版本。
好的,在调试器下运行它。点击暂停按钮,查看调用堆栈。机会是19/20,你会看到什么是额外的时间。 做几次以确定。
当我这样做时,它正在进行类验证方法,这些方法在发布模式下关闭。 通常,它是通过不同的路径,一遍又一遍地重新验证相同的数据。
在你的情况下,它可能就是那些迭代器。 如果你没有做太多其他事情,他们很容易占据主导地位。
但不要猜。
答案 2 :(得分:2)
一个问题是,在VC ++调试版本中默认启用的“快速调试检查”会使代码减慢最多五倍。他们偶尔会发现错误,但通常不足以证明你所看到的成本是合理的。有关详细信息,请参阅我的博文:
Visual C++ Debug Builds–”Fast Checks” Cause 5x Slowdowns
将它们关闭,每个小功能都会明显加快。
答案 3 :(得分:1)
如果您的减速仅在调试器内部进行初始化(但是如果您将Debug构建作为常规应用程序运行则不会),则它是由Visual Studio加载您正在使用的所有库的调试符号引起的。这是预期的,但您可以微调从调试首选项加载哪些符号。
缺乏优化当然会减慢一般情况,但不是专门在调试器内启动时。