为什么std::queue
中的析构函数非常慢?看看我的例子:
void test()
{
int total = 17173512;
std::queue<int> q;
for(int i = 0; i < total; i++)
q.push(i); //Push is very fast.
std::cout<<"Done"<<std::endl; //Less than a second.
}
test();
std::cout<<"Done"<<std::endl; //This takes several minutes!!
std::vector
中的析构函数非常快......
更新: 我的编译器/ IDE是Visual Studio 2012 Visual C ++。
int main(int argc, char **argv)
{
int total = 17173512;
std::queue<int> q;
for(int i = 0; i < total; i++)
q.push(i);
std::cout<<"Done0"<<std::endl; //This takes less than a second.
while(!q.empty())
q.pop();
//This takes less than a second. Memory should be deallocated here!
std::cout<<"Done1"<<std::endl;
//Waiting forever, i.e. deallocating(HERE??) memory EXTREMELY SLOWLY.
//I can see how the memory is being deallocated here in windows task manager!
return 0;
}
使用vector:
int main(int argc, char **argv)
{
int total = 17173512;
std::vector<int> q(total);
for(int i = 0; i < total; i++)
q[i] = 2000;
std::cout<<"Done"<<std::endl;
return 0; //Extremely fast.
}
更新2:
现在一切都解决了!我卸载了Visual Studio 2012 + visual c ++。我安装了Visual Studio Community 2015,一切都快得多,按预期工作!
答案 0 :(得分:2)
我已使用此代码进行衡量:
int main(){
auto test = [](){
auto start = std::chrono::system_clock::now();
int total = 17173512;
std::queue<int> q;
for (int i = 0; i < total; i++){
q.push(i); //Push is very fast.
}
auto end = std::chrono::system_clock::now();
return end - start;
};
auto start = std::chrono::system_clock::now();
auto pushing_time = test();
auto end = std::chrono::system_clock::now();
auto deleting_time = (end - start) - pushing_time;
std::cout << "Pushing Time:" << pushing_time.count() << '\n';
std::cout << "Deleting Time:" << deleting_time.count() << '\n';
return 0;
}
<强>环境:强>
<强>结果:强>
发布模式,\ O2,附加到VS:
推送时间:71403190
删除时间:5293067027
发布模式,\ O2,未附加到VS:
推送时间:3743267
删除时间:1741230
所以从结果来看,我怀疑你是在运行它附加到某个IDE。
答案 1 :(得分:0)
当n个元素的向量被破坏时,n个元素被破坏,然后meory在1个操作中被释放(连续的集团)。
对于要销毁的队列,在n个操作中释放内存,并且内存管理系统必须管理这些n个自由集合(对于链接列表中的ex)。因此,内存管理可以显着影响性能
答案 2 :(得分:0)
一般来说,Christophe对容器类型是正确的,但这里的问题与容器类型无关。我们期望内存分配和释放几乎相等。我在调试和发布模式下分析了MSVC2010中的代码。分析表明删除操作比新操作符更耗时。似乎删除操作包括一些额外的操作,但我不能准确地知道它。