Jug*_*lum 5 c++ stl sorted set
我在Visual Studio 2010中使用C++.我有一个STL集,当我的程序关闭时,我将其保存到文件中.下次程序启动时,我将(已排序的)数据加载回集合中.我正在尝试优化加载过程,我遇到了麻烦.我怀疑问题是频繁的重新平衡,我正在寻找一种方法来避免这种情况.
首先,我没有进行优化,使用"set-> insert(const value_type&x)"
时间:约5.5分钟
然后我尝试使用insert()的版本,在其中传递insert()的位置提示:
iterator insert ( iterator position, const value_type& x );
Run Code Online (Sandbox Code Playgroud)
粗略地说,我这样做了:
set<int> My_Set;
set<int>::iterator It;
It = My_Set.insert (0);
for (int I=1; I<1000; I++) {
It = My_Set.insert (It, I); //Remember the previous insertion's iterator
}
Run Code Online (Sandbox Code Playgroud)
时间:约5.4分钟
几乎没有任何进步!我不认为问题是从文件读取开销 - 注释掉insert()会将时间减少到2秒.我认为问题不在于复制对象的开销 - 它是一个带有int和char的Plain Old Data对象.
我唯一能想到的是该套装不断重新平衡.
1.)你同意我的猜测吗?
2.)有没有办法在我加载集合时"暂停"重新平衡,然后在结束时重新平衡一次?(或者......那会有帮助吗?)
3.)是否有更智能的方法来加载已排序的数据,即不是简单地从最低到最高?也许交替我的插入,以便它不必经常平衡?(示例:插入1,1000,2,999,3,998 ......)
关于我们谈论了多少元素?
我用10.000.000个整数(在向量中准备)进行了一个简短的测试,并以三种不同的方式将它们插入到集合中.
准备输入:
std::vector<int> input;
for(int i = 0; i < 10*1000*1000; ++i) {
input.push_back(i);
}
Run Code Online (Sandbox Code Playgroud)
发布:2,4秒/调试:110,8秒
std::set<int> mySet;
std::for_each(input.cbegin(), input.cend(), [&mySet] (int value) {
mySet.insert(value);
});
Run Code Online (Sandbox Code Playgroud)
insert(itBegin, itEnd):
发布:0,9秒/调试:47,5秒
std::set<int> mySet;
mySet.insert(input.cbegin(), input.cend());
// this is also possible - same execution time:
std::set<int> mySet(input.cbegin(), input.cend());
Run Code Online (Sandbox Code Playgroud)
因此插入可能会大幅加速,但即使是缓慢的方式也应该远离几分钟.
我同时用调试模式进行了测试 - 哇 - 我知道调试成本的性能,但它比我想象的要多.使用50.000.000元素在调试模式下有一个错误的alloc,所以我将我的帖子更新为10.000.000元素,并显示了发布和调试版本的时间.
您可以在这里看到巨大的差异 - 使用更快的解决方案50次.
此外,快速解决方案(insert(itBegin, itEnd))似乎与元素数量呈线性关系(使用预先分类的数据!).普通测试的元素数量增加了5倍,插入时间从4,6减少到0.9,大约是5倍.