VS2005调试模式和发布模式之间存在巨大的性能影响
Huge performance impact between VS2005 debug mode and release mode
我遇到一个问题,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 *> > >
我想是迭代器操作没有内联导致了这种巨大的差异。有什么方法可以改进吗?我可以在发布模式下调试,只要仍然可以在源代码中逐行执行并检查所有变量值。
差异正常。我会做的是放置
#pragma optimize("",off)
#pragma optimize("",on)
围绕要检查的方法,并将构建的其余部分保持在发布模式。
6分钟与20秒的比例为18:1(为了简单起见,称之为20:1)。
这意味着调试版本95%的时间都在做一些发布版本没有做的额外事情。
好的,在调试器下运行它。点击暂停按钮并查看调用堆栈。19/20的机会是,你会看到是什么在占用额外的时间。做几次以确定。
当我这样做的时候,它正在做类验证方法,这些方法在发布模式下是关闭的。它经常通过不同的路径一遍又一遍地重新验证相同的数据。
在您的情况下,很可能是那些迭代器。如果你不做太多其他事情,他们很容易占据主导地位。
但不要猜测。
一个问题是,在VC++调试构建中默认启用的"快速调试检查"会使代码速度减慢五倍。他们偶尔会发现错误,但并不经常足以证明你所看到的成本是合理的。查看我的博客文章了解更多详细信息:
Visual C++调试构建-"快速检查"导致慢5倍
关闭它们,每一个小功能都会明显加快。
如果您的速度减慢只是因为调试器内部的初始化(但不是因为您将Debug内部版本作为常规应用程序运行),则是由于Visual Studio加载了您正在使用的所有库的调试符号。这是意料之中的事,但您可以微调从调试首选项加载的符号。
缺乏优化当然会在一般情况下减慢速度,但不会特别是在调试器内部启动时。
- C++模板来检查友元函数的存在
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- 为什么在保护模式下继承升级不起作用
- C++:对不存在的命名空间使用命名空间指令
- 如何在全屏模式下(在OpenGL中)使背景透明
- 文件模式标志"ios::app"是否用于删除文件(如果文件已存在)?
- 用户定义的文本运算符(在原始模式下)存在问题
- 在读/写/附加模式下打开QFile后,我能检测到它是否存在吗
- VS2005调试模式和发布模式之间存在巨大的性能影响
- 如何仅当文件存在时才使用追加模式打开文件
- VBO 与即时模式 (glBegin/glEnd) 的行为是否存在任何行为差异
- 适用于预先存在的类层次结构的函数的最佳模式
- 什么设计模式将数据部分保存在持久存储 (SQL) 中,部分保存在 RAM(内存)中
- 在or条件语句中是否存在强制对两个表达式求值的模式或技巧?
- 命令设计模式的实现存在一些错误
- 是否存在用于在子类的数据上实施规则的设计模式
- 是否存在作为一组Clang工具实现的C++重构模式
- 对象寿命相关;下面的问题不存在一个术语/模式什么的吗