2010-07-06 73 views
5

我有以下代码(这在很大程度上遵循第一个示例:http://www.boost.org/doc/libs/1_42_0/libs/multi_index/doc/examples.html))。出于某种原因,只有10000多插入到多索引,它需要几分钟来运行该程序。我做错了什么或这是预期的?提高缓慢插入性能的多索引

struct A 
{ 
    int id; 
    int name; 
    int age; 
    A(int id_,int name_,int age_):id(id_),name(name_),age(age_){} 
}; 


/* tags for accessing the corresponding indices*/ 
struct id{}; 
struct name{}; 
struct age{}; 

typedef multi_index_container< 
    A, 
    indexed_by< 
    ordered_unique< 
     tag<id>, BOOST_MULTI_INDEX_MEMBER(A,int,id)>, 
    ordered_non_unique< 
     tag<name>,BOOST_MULTI_INDEX_MEMBER(A,int,name)>, 
    ordered_non_unique< 
     tag<age>, BOOST_MULTI_INDEX_MEMBER(A,int,age)> > 
> A_set; 



int main() 
{ 
    A_set es; 

    for (int a = 0; a != 10000; a++) { 
    es.insert(A(a,a+1,a+2)); 
    } 
    return 0; 
} 
+1

您是否设置了NDEBUG宏?如果我设置它,代码就会很快。 – pmr 2010-07-06 11:28:53

回答

11

你有没有机会在调试模式下编译?它完成近即时与Visual Studio 2008中默认的发布配置如果你在调试模式下编译和你差不多跟着例如以信,包括预处理器的东西,仍然有这一部分:

#ifndef NDEBUG 
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING 
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE 
#endif 

然后删除/禁用这些定义也将显着加快执行时间。 (至少在我的机器上是180x,并没有让它完成。)我不知道在调试版本中禁用或删除这些东西的后果是什么。

+0

谢谢,我不知道要去那里看看。我也许应该在代码中包含它。 – tsiki 2010-07-06 11:29:54

+0

谢谢!我做了完全相同的事情,并从示例中粘贴了这些... – nhed 2012-03-30 22:22:12

+0

请注意,强烈建议在调试时使用'BOOST_MULTI_INDEX_ENABLE_SAFE_MODE'。它不会导致你看到的放缓,并在你的代码中发现微妙的错误。 'BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING'是这里的罪魁祸首。它检查升压代码中的错误*,除非您怀疑升压代码是越野车,否则不应设置它。 – Chronial 2015-09-20 13:45:27

1

从我自己与boost::bi_map的经验(这是基于多指标容器我所知),我不得不说,这些多指标容器遗憾的是相对缓慢的。但是,这不是用于插入性能。所以我不明白你为什么这么慢。

我做了一个小基准,比较boost::bi_map与两个boost::unordered_map s。对于两种方法,插入100'000个唯一值都是1秒左右。但是,对于unordered_map,查询50000000个值为10秒,对于有序映射(即使用整数键),查询值为26秒。 (我们最好的内部数据结构在1秒左右执行查找)。

4

几分钟似乎很慢 - 我期望现代CPU最多秒。 Boost倾向于使用许多小的函数,在调试版本中运行速度比优化版本的编译速度慢得多。

也验证BOOST_MULTI_INDEX_ENABLE_SAFE_MODEBOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING没有设置。这些都执行额外的运行时检查。