为什么从 VS2010 迁移到 VS2015 时,相同的代码会慢两倍?
Why same code is twice slower when migrated from VS2010 to VS2015?
我最近将一些遗留代码从 Visual Studio 2010 32 位移植到 Visual Studio 2015 64 位。
我的 CPPUNIT 测试速度时间(在调试模式下)增加了两倍以上。我真的很惊讶,所以我尝试在更小的代码段上隔离和重现问题:
#include <deque>
#include <iostream>
#include <string>
#include <time.h>
class Message
{
public:
Message(const std::string &shortDescription)
: m_shortDescription(shortDescription)
{
m_details.push_back( shortDescription );
}
inline const std::string& str() const { return m_shortDescription; }
private:
std::string m_shortDescription;
typedef std::deque<std::string> Details;
Details m_details;
};
int main( int argc, char* argv[] )
{
std::cout << sizeof(size_t) << std::endl;
clock_t started = clock();
std::string str;
for (size_t i = 0; i != 1000000; ++i)
{
Message msg("foo");
}
std::cout << static_cast<double>(clock()-started)/CLOCKS_PER_SEC << "secs" << std::endl;
std::cin >> str;
return 0;
}
使用 Visual Studio 2015(x64 或 x86)在调试模式下编译时,此基本程序性能会急剧下降:
- Visual Studio 2010,调试,x64:~10s
- Visual Studio 2010,调试,x86:~10s
- Visual Studio 2015,调试,x64:~20s
- Visual Studio 2015,调试,x86:~20s
在 Release 中,VS2015 生成更快的代码:
- Visual Studio 2010,发布,x64:~1.3s
- Visual Studio 2010,发布,x86:~1.3s
- Visual Studio 2015 年,发布,x64:~0.2s
- Visual Studio 2015,发布,x86:~0.2s
如何使 Visual Studio 调试代码如此缓慢?他们是否扩展了对 STL 容器的 _DEBUG 检查(std::deque::push_back
是此处唯一使用 CPU 的相关代码)?
绝对优化。您可以进行一项众所周知的更改 - 您可以试验其他更改并确定在调试版本中哪些是可行的。 (优化可能会使步骤变得困难。)
在您的项目属性配置中,将 C/C++->代码生成->基本运行时检查设置为默认值。
您的代码的 x86 调试时间从大约 17 秒减少到 9 秒,仅此一项更改。
我只有 VS 2013 方便测试,但同样的事情发生在 VS 2015 中。
比较生成的代码或阅读 this blog post。
Microsoft 几乎在 MSVC++ 的每个主要版本中都提高了对容器和迭代器执行的验证级别。
您可以通过禁用某些验证来减少调试运行所花费的时间。例如,将以下内容添加到源文件的顶部:
#define _HAS_ITERATOR_DEBUGGING 0
请注意,我怀疑上述配置宏也会减少 VS2010 调试运行时间。
有关详细信息,请参阅以下文档:
一般来说,我建议启用迭代器调试,除非运行时命中无法忍受。它对于防止错误使用迭代器非常有帮助。
我最近将一些遗留代码从 Visual Studio 2010 32 位移植到 Visual Studio 2015 64 位。
我的 CPPUNIT 测试速度时间(在调试模式下)增加了两倍以上。我真的很惊讶,所以我尝试在更小的代码段上隔离和重现问题:
#include <deque>
#include <iostream>
#include <string>
#include <time.h>
class Message
{
public:
Message(const std::string &shortDescription)
: m_shortDescription(shortDescription)
{
m_details.push_back( shortDescription );
}
inline const std::string& str() const { return m_shortDescription; }
private:
std::string m_shortDescription;
typedef std::deque<std::string> Details;
Details m_details;
};
int main( int argc, char* argv[] )
{
std::cout << sizeof(size_t) << std::endl;
clock_t started = clock();
std::string str;
for (size_t i = 0; i != 1000000; ++i)
{
Message msg("foo");
}
std::cout << static_cast<double>(clock()-started)/CLOCKS_PER_SEC << "secs" << std::endl;
std::cin >> str;
return 0;
}
使用 Visual Studio 2015(x64 或 x86)在调试模式下编译时,此基本程序性能会急剧下降:
- Visual Studio 2010,调试,x64:~10s
- Visual Studio 2010,调试,x86:~10s
- Visual Studio 2015,调试,x64:~20s
- Visual Studio 2015,调试,x86:~20s
在 Release 中,VS2015 生成更快的代码:
- Visual Studio 2010,发布,x64:~1.3s
- Visual Studio 2010,发布,x86:~1.3s
- Visual Studio 2015 年,发布,x64:~0.2s
- Visual Studio 2015,发布,x86:~0.2s
如何使 Visual Studio 调试代码如此缓慢?他们是否扩展了对 STL 容器的 _DEBUG 检查(std::deque::push_back
是此处唯一使用 CPU 的相关代码)?
绝对优化。您可以进行一项众所周知的更改 - 您可以试验其他更改并确定在调试版本中哪些是可行的。 (优化可能会使步骤变得困难。)
在您的项目属性配置中,将 C/C++->代码生成->基本运行时检查设置为默认值。
您的代码的 x86 调试时间从大约 17 秒减少到 9 秒,仅此一项更改。
我只有 VS 2013 方便测试,但同样的事情发生在 VS 2015 中。
比较生成的代码或阅读 this blog post。
Microsoft 几乎在 MSVC++ 的每个主要版本中都提高了对容器和迭代器执行的验证级别。
您可以通过禁用某些验证来减少调试运行所花费的时间。例如,将以下内容添加到源文件的顶部:
#define _HAS_ITERATOR_DEBUGGING 0
请注意,我怀疑上述配置宏也会减少 VS2010 调试运行时间。
有关详细信息,请参阅以下文档:
一般来说,我建议启用迭代器调试,除非运行时命中无法忍受。它对于防止错误使用迭代器非常有帮助。