2012-05-21 7 views
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 и нашел какую-то смешную проблему с производительностью. Приведенный выше код хорошо работает как в отладке, так и в выпуске build (ctrl + f5), но при подключении отладчика (f5) вызов dtor для класса unique_ptr является невыносимо медленным. Результат машинного кода довольно оптимизирован, поэтому я не ожидаю, что это проблема компилятора, а не отладчик, но я не знаю, как с этим бороться. Мой вопрос:Смешно медленный вызов unique_ptr dtor при подключении отладчика (msvc)

  • Невозможно ли воспроизвести эту проблему на вашей машине?
  • В чем причина такого поведения?
  • Есть ли обходной путь?
+0

Попробуйте промыть после каждого printf. – Pubby

+0

@Pubby: Это не будет иметь никакого значения, всего 3 'printf's total, а не один для каждой итерации цикла. –

+0

Я смог воспроизвести это на своем выпуске VS2010. – RedX

ответ

6

Замедление вызвано проверкой памяти, которая происходит всякий раз, когда освобождается память. Однако это специальная куча системы/отладчика, и вы не можете контролировать ее внутри своей программы.

Существует great article on the issue. Подводя итог: вы должны установить переменную среды, чтобы отключить ее!

К счастью, вы можете установить переменные среды, специфичные для проекта, из параметров «Отладка» в настройках проекта для вашего проекта, чтобы переменная окружения применялась только к вашей программе.

Я использовал эту упрощенную программу для тестирования:

#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 как переменная окружения (или общесистемный, которые я не буду рекомендовать, или через опции отладки), код выполняется в примерно столько же времени, независимо от того, подключен ли отладчик или нет.