当调试器附加时(msvc),unique_ptr的析构函数调用非常缓慢

7
struct test_struct
{
    test_struct() {}
    ~test_struct() {}
};

#include <vector>
#include <memory>
#include <cstdio>

int main()
{
    printf("ctor begin\n");
    {
        std::vector<std::unique_ptr<test_struct>> test_vec;
        const int count = 100000;

        for (auto i = 0; i < count; i++) {
            test_vec.emplace_back(new test_struct);
        }
        printf("dtor begin\n");
    }
    printf("dtor end\n");
}

我正在使用VS2010,并发现一些荒唐的性能问题。上面的代码在调试和发布版(ctrl+f5)中都表现良好,但当附加调试器(f5)时,unique_ptr类的dtor调用变得难以忍受地缓慢。生成的机器代码非常优化,因此我不认为是编译器问题,而是调试器的问题,但我不知道该怎么处理它。我的问题是:

  • 您的计算机上是否能够重现此问题?
  • 这种行为的原因是什么?
  • 有没有任何解决方法?

尝试在每个printf之后刷新。 - Pubby
@Pubby:这不会有任何影响,总共只有3个printf,而不是每次循环迭代都有一个。 - Adam Rosenfield
我能够在我的VS2010 Express版上重现这个问题。 - RedX
1个回答

6
减速是由每次释放内存时发生的内存检查引起的。但是,这是一个特殊的系统-/调试器级堆栈,您无法从程序内部控制它。
有一篇关于此问题的精彩文章。总结起来:您必须设置环境变量才能禁用它!
幸运的是,您可以从项目设置中的调试选项中设置项目特定的环境变量,以便仅将环境变量应用于您的程序。
我使用这个简化的程序进行测试:
#include <iostream>
#include <memory>
#include <vector>

int main()
{
    std::cout << "ctor begin" << std::endl;
    {
        std::vector<std::unique_ptr<int>> test_vec;

        for (unsigned i = 0; i < 100000; i++)
            test_vec.emplace_back(new int);

        std::cout << "dtor begin" << std::endl;
    }
    std::cout << "dtor end" << std::endl;
}

通过将_NO_DEBUG_HEAP=1设置为环境变量(可以系统范围内设置,但我不建议这样做,或通过调试选项),代码的运行时间大致相同,无论是否连接了调试器。

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