2010-07-06 67 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沒有設置。這些都執行額外的運行時檢查。