让我重新陈述 Alexander 的建议,即您对程序进行概要分析,以便了解问题的真正所在。我强烈怀疑 Boost.MultiIndex 本身会像你说的那样慢。以下程序测量创建 order_sell 容器(没有 Boost.Pool)、用 10,000 个随机订单填充它并销毁它所花费的时间:
Live Coliru Demo
#include <algorithm>
#include <array>
#include <chrono>
#include <numeric>
std::chrono::high_resolution_clock::time_point measure_start,measure_pause;
template<typename F>
double measure(F f)
{
using namespace std::chrono;
static const int num_trials=10;
static const milliseconds min_time_per_trial(200);
std::array<double,num_trials> trials;
volatile decltype(f()) res; /* to avoid optimizing f() away */
for(int i=0;i<num_trials;++i){
int runs=0;
high_resolution_clock::time_point t2;
measure_start=high_resolution_clock::now();
do{
res=f();
++runs;
t2=high_resolution_clock::now();
}while(t2-measure_start<min_time_per_trial);
trials[i]=duration_cast<duration<double>>(t2-measure_start).count()/runs;
}
(void)res; /* var not used warn */
std::sort(trials.begin(),trials.end());
return std::accumulate(
trials.begin()+2,trials.end()-2,0.0)/(trials.size()-4);
}
void pause_timing()
{
measure_pause=std::chrono::high_resolution_clock::now();
}
void resume_timing()
{
measure_start+=std::chrono::high_resolution_clock::now()-measure_pause;
}
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
using namespace boost::multi_index;
struct order
{
unsigned int id;
unsigned int quantity;
double price;
};
struct id{};
struct price{};
typedef multi_index_container<
order,
indexed_by<
hashed_unique<
tag<id>,BOOST_MULTI_INDEX_MEMBER(order, unsigned int, id)>,
ordered_non_unique<
tag<price>,BOOST_MULTI_INDEX_MEMBER(order ,double, price),
std::less<double> >
>
> order_sell;
#include <iostream>
#include <random>
int main()
{
std::cout<<"Insertion of 10,000 random orders plus container cleanup\n";
std::cout<<measure([](){
order_sell os;
std::mt19937 gen{34862};
std::uniform_int_distribution<unsigned int> uidist;
std::uniform_real_distribution<double> dbdist;
for(unsigned int n=0;n<10000;++n){
os.insert(order{uidist(gen),0,dbdist(gen)});
}
return os.size();
})<<" seg.\n";
}
当在-O3 模式下使用 Coliru 使用的任何后端运行时,我们得到:
插入 10,000 个随机订单和容器清理
0.00494657 段。
我的机器(Intel Core i5-2520M @2.50GHz)中的 VS 2015 发布模式产生:
插入 10,000 个随机订单和容器清理
0.00492825 段。
因此,这比您报告的速度快 20 倍左右,并且我的测量中包括了容器销毁和随机数生成。
一些额外的观察:
-
boost::object_pool 不提供标准库为与容器的互操作性而指定的分配器接口。您可能想改用boost::pool_allocator(我玩过它,但似乎并没有提高速度,但您的里程可能会有所不同)。
- John 的回答似乎暗示 Boost.MultiIndex 是次优的,因为它将节点与值或类似的东西分开分配。事实上,该库在内存分配方面尽可能高效,而且您无法使用 Boost.Intrusive 做得更好(实际上,您可以获得相同的效果)。如果您对 Boost.MultiIndex 内部数据结构的外观感到好奇,请查看我的 this answer。特别是,对于带有散列索引和有序索引的
order_sell 容器,每个值都进入它自己的 one 节点,另外还有一个单独的所谓的桶数组(一个指针数组) 的长度与元素的数量大致相同。对于基于节点的数据结构,没有什么比这更好的了(如果您想摆脱迭代器的稳定性,您可以设计出更节省内存的方案)。