为什么我的STL代码在调试器/集成开发环境下运行速度如此缓慢?

5
我正在运行以下代码,使用Visual Studio 2008 SP1,在Windows Vista Business x64上,四核机器,8GB内存。
如果我构建一个发布版本,并从命令行运行它,它会报告31ms。如果我使用F5从IDE启动它,则会报告23353ms。
以下是时间:(所有Win32版本)
- DEBUG,命令行:421ms - DEBUG,从IDE:24,570ms - RELEASE,命令行:31ms - RELEASE,从IDE:23,353ms
代码:
#include <windows.h>
#include <iostream>

#include <set>
#include <algorithm>
using namespace std;

int runIntersectionTestAlgo()
{   

    set<int> set1;
    set<int> set2;
    set<int> intersection;


    // Create 100,000 values for set1
    for ( int i = 0; i < 100000; i++ )
    {
        int value = 1000000000 + i;
        set1.insert(value);
    }

    // Create 1,000 values for set2
    for ( int i = 0; i < 1000; i++ )
    {
        int random = rand() % 200000 + 1;
        random *= 10;

        int value = 1000000000 + random;
        set2.insert(value);
    }

    set_intersection(set1.begin(),set1.end(), set2.begin(), set2.end(), inserter(intersection, intersection.end()));

    return intersection.size(); 
}

int main(){
    DWORD start = GetTickCount();

    runIntersectionTestAlgo();

    DWORD span = GetTickCount() - start;

    std::cout << span << " milliseconds\n";
}

你可能想查看Markdown的帮助,以便更好地格式化代码。 - crashmstr
是的,说实话,我发现这很难处理。我点击了“代码”按钮并粘贴了我的代码,结果它把它搞得一团糟。 - waterlooalex
将代码粘贴到第一行,然后选择它并单击代码按钮。 :) - jalf
这并不像你说的那么容易。 :) - waterlooalex
1
这个问题实际上可以在没有代码的情况下解决 :) 但前提是你必须先经历过它。 - MSN
3个回答

11
默认情况下,在Microsoft调试器(windbg、kd、cdb、Visual Studio Debugger)下运行会强制Windows使用调试堆而不是默认堆。在Windows 2000及以上版本中,默认堆是低碎片堆,与调试堆相比,性能非常出色。您可以使用HeapQueryInformation来查询正在使用的堆类型。
要解决特定问题,您可以使用此KB文章中推荐的众多选项之一:为什么低碎片堆(LFH)机制可能会在运行Windows Server 2003、Windows XP或Windows 2000的某些计算机上被禁用 对于Visual Studio,我更喜欢将_NO_DEBUG_HEAP=1添加到项目属性->配置属性->调试->环境中。这对我总是有效。

1
谢谢,问题解决了。一旦我设置了_NO_DEBUG_HEAP=1,那么代码在调试器附加的情况下运行速度与没有附加时一样快。虽然我想这样做可能会失去一些保护/问题检测。 - waterlooalex
1
你会失去很多调试能力。 - MSN

3
按下VS IDE中的暂停按钮后,可以看到额外的时间似乎花费在了malloc/free上。这使我相信,如果调试器附加,则MS的malloc和free实现中的调试支持具有额外的逻辑。这可以解释从控制台和调试器中获得的时间差异。
编辑:通过使用CTRL+F5 v. F5(在我的机器上为1047ms v. 9088ms)进行确认。

我也注意到了,有时候出现错误会显示malloc的代码。 - waterlooalex

0

听起来好像只是在连接调试器时发生的问题。然而,我无法想象仅仅因为连接调试器,性能就会从30毫秒变成23,000毫秒,尤其是当我的其余代码似乎无论是否连接调试器都运行得一样快时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接