2011-03-10 121 views
6

我正在使用boost :: multi_index与我想根据其大小索引的数据类型。但是,此数据类型的size()成员函数执行起来很昂贵。 multi_index是否缓存从其关键提取器获得的值?例如,如果我创建了一个带有成员函数键(element.size())的有序索引的multi_index容器,并且插入了一个元素,该元素的大小将其放置在容器中间的某个位置,容器将重新创建 - 在查找正确的插入点之前,在遍历其内部数据结构时访问它所访问的所有元素上的size()成员函数?是否缓存boost multi_index提取的键?

回答

9

那么,对于成员函数索引的文件说,他们称之为引用的成员函数:http://www.boost.org/doc/libs/1_46_0/libs/multi_index/doc/reference/key_extraction.html#key_extractors

但是,当有疑问,简介:

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/mem_fun.hpp> 
#include <boost/multi_index/indexed_by.hpp> 
#include <boost/multi_index/hashed_index.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <iostream> 
#include <vector> 
#include <algorithm> 

using namespace std; 

namespace bmi = boost::multi_index; 

int g_calls = 0; 
struct A 
{ 
    explicit A(int sz) : m_size(sz) { } 
    int size() const { ++g_calls; return m_size; } 
private: 
    int m_size; 
}; 

typedef boost::multi_index_container< 
    A*, 
    bmi::indexed_by< 
    bmi::ordered_non_unique< 
     BOOST_MULTI_INDEX_CONST_MEM_FUN(A,int,A::size) 
    > 
    > 
> container_t; 

int main() 
{ 
    container_t cont; 
    int n = 100; 
    vector<int> o(2*n+1); 
    for(int i = 0; i != 2*n+1; ++i) 
    o[i] = i; 
    random_shuffle(o.begin(), o.end()); 

    for(int i = 0; i != n; ++i) 
    cont.insert(new A(o[i])); 
    cout << "Calls to A::size(): "<< g_calls << endl; 
    for(int i = n+1; i <= 2*n; ++i) 
    cont.insert(new A(o[i])); 
    cout << "Calls to A::size(): "<< g_calls << endl; 
    cont.insert(new A(o[n])); 
    cout << "Calls to A::size(): "<< g_calls << endl; 
    for(int i = 0; i != o.size(); ++i) 
    cont.find(o[i]); 
    cout << "Calls after calling find " << o.size() << " times: "<< g_calls << endl; 
    return 0; 
} 

给出(使用Boost 1.46)以下的输出:

Calls to A::size(): 629 
Calls to A::size(): 1465 
Calls to A::size(): 1474 
Calls after calling find 201 times: 3262 

所以,看起来答案是不,它不缓存值

+0

太棒了,谢谢。这太糟糕了。猜猜我必须包装我的类型。 – vsekhar 2011-03-10 23:21:48