- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试实现一个 boost::multi_index 应用程序,但性能非常糟糕:插入 10,000 个对象几乎需要 0.1 秒,这是 Not Acceptable 。因此,当我查看文档并发现 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> >
>,
boost::object_pool<order>
> order_sell;
一般来说,编译器不喜欢在 order_sell 声明中将 boost::object_pool 表达为分配器。
最佳答案
让我重申一下 Alexander 的建议,即您分析程序以了解问题的真正所在。我强烈怀疑 Boost.MultiIndex 本身会像你说的那样慢。以下程序测量了创建 order_sell
容器(没有 Boost.Pool)、用 10,000 个随机订单填充它并销毁它所花费的时间:
#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";
}
当 Coliru 使用任何后端以 -O3
模式运行时,我们得到:
Insertion of 10,000 random orders plus container cleanup0.00494657 seg.
我的机器(Intel Core i5-2520M @2.50GHz)中的 VS 2015 Release模式产生:
Insertion of 10,000 random orders plus container cleanup0.00492825 seg.
因此,这比您报告的快 20 倍左右,而且我在测量中包括容器销毁和随机数生成。
一些额外的观察:
boost::object_pool
不提供标准库为与容器的互操作性指定的分配器接口(interface)。您可能想使用 boost::pool_allocator
取而代之(我已经玩了一会儿,但似乎并没有 boost 速度,但你的里程可能会有所不同)。order_sell
容器,每个值都进入其自己的一个节点,另外还有一个单独的所谓的桶数组(指针数组)长度与元素数量大致相同。对于基于节点的数据结构,没有比这更好的了(如果您想放弃迭代器的稳定性,您可以设计出内存效率更高的方案)。关于c++ - 如何使用 boost::object_pool 作为 boost::multi_index 分配器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37095641/
我想为 std::map 指定 allocator。所以写一个自定义的,从here中获取基本代码约苏蒂斯。我想使用 boost::object_pool 来获得高性能。但是boost::object_
我想创建一个对象池,但我希望它只在我的内存堆的特定段上分配内存。有没有办法使用 boost 来做到这一点? 最佳答案 Boost.Pool 的 object_pool允许用户通过提供 UserAllo
boost::object_pool 是同步的吗? 最佳答案 C++ 没有指定任何关于线程安全的内容,因此如果没有提及,它可能不涉及线程。有时,Boost 提供开箱即用的线程安全的东西,这不是其中之一
在询问 Is there a faster heap allocation/deallocation mechanism available than boost::object_pool? 后,我得
我的应用程序有一个类“MyClass”。它的对象是从 Boost Object_pool 构建的。 我需要通过 Boost 二进制序列化对此类对象进行序列化/反序列化。 用于序列化 - 我从池中取出一
我尝试使用 boost::object_pool 创建一个包含 vector 作为其成员数据的对象。这是代码。 #include #include #include class A { publ
这周我发现了 boost::object_pool 并且惊讶于它比普通的新建和删除快了大约 20-30%。 为了测试,我编写了一个小型 C++ 应用程序,它使用 boost::chrono 为不同的堆
这是一个由以下代码说明的两部分问题: #include #include #include struct Foo { Foo(int i) : _i(i) {} void* oper
我正在尝试实现一个 boost::multi_index 应用程序,但性能非常糟糕:插入 10,000 个对象几乎需要 0.1 秒,这是 Not Acceptable 。因此,当我查看文档并发现 bo
是否可以通过非 const 引用使用 boost::object_pool<>::construct? 以下代码段无法编译 (VS2010): foo::foo(bar & b) { } static
我是一名优秀的程序员,十分优秀!