2011-03-10 14 views
6

Estoy usando boost :: multi_index con un tipo de datos que me gustaría indexar en función de su tamaño. Sin embargo, la función miembro de size() de este tipo de datos es costosa de ejecutar. ¿Multi_index almacena en caché los valores que obtiene de sus extractores de claves?¿Se almacenan en memoria caché las claves extra de boost multi_index?

Por ejemplo, si crease un contenedor multi_índice con un índice ordenado con una tecla de función miembro (elemento.size()), e insertara un elemento cuyo tamaño lo pusiera en algún lugar en el medio del contenedor, ¿se retendría el contenedor? -invocar la función de miembro de size() en todos los elementos que visita al atravesar su estructura de datos interna antes de encontrar el punto de inserción correcto?

Respuesta

9

Bueno, la documentación de los indexadores función miembro dice que ellos llaman la función de referencia de usuario: http://www.boost.org/doc/libs/1_46_0/libs/multi_index/doc/reference/key_extraction.html#key_extractors

Pero ante la duda, el perfil:

#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; 
} 

da el siguiente resultado (usando 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 

Por lo tanto, parece que la respuesta es no, no lo hace caché valores.

+0

Impresionante, gracias. Es muy malo. Supongo que tendré que ajustar mi tipo. – vsekhar

Cuestiones relacionadas