Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ridiculously slow unique_ptr dtor call when debugger is attached (msvc)

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");
}

I'm using VS2010, and found some ridiculous performance issue. The code above works well both in debug and release build (ctrl+f5), but when debugger is attached(f5), dtor call for unique_ptr class is intolerably slow. The result machine code is fairly optimized, so I don't expect that it's compiler issue rather than debugger's, but I don't know how to deal with it. My question is

  • Is this problem able to be reproduced on your machine?
  • What's the reason of this behaviour?
  • Is there any workaround?
like image 645
summerlight Avatar asked May 21 '12 05:05

summerlight


1 Answers

The slowdown is caused by memory checking that occurs whenever memory is freed. However, this is a special system-/debugger-level heap, and isn't anything you can control from within your program.

There's a great article on the issue. To summarize: you have to set an environment variable to disable it!

Luckily, you can set project-specific environment variables from the Debugging options in the Project Settings for your project, so that the environment variable is only applied to your program.

I used this simplified program to test:

#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;
}

By setting _NO_DEBUG_HEAP=1 as an environment variable (either system-wide, which I won't recommend, or through the Debugging options), the code runs in roughly the same amount of time irrespective of whether or not the debugger is attached.

like image 197
GManNickG Avatar answered Sep 28 '22 07:09

GManNickG