Search code examples
c++boostpoolallocator

Boost pool for unordered set of custom objects


I'm having a hard time finding an example for this. My code looks like this:

typedef boost::unordered_set<CustomObject, boost::hash<CustomObject>, 
  CustomObjectEqual, allocator<CustomObject> > CustomObjectSet;

I've tried to use fast_pool_allocator directly but this leads to a compiler error (using std::allocator works). My questions are:

  1. Do I need to create a custom allocator for CustomObject?
  2. Does this increase the speed of my program?

Solution

  • Question 1: Do I need to create a custom allocator for CustomObject?

    No. It will compile without it. The allocator uses default parameters. In an example below are these the same:

    using fast_allocator = boost::fast_pool_allocator<
        CustomObject,
        boost::default_user_allocator_new_delete,
        boost::mutex,
        32,
        0>;
    
    using fast_allocator = boost::fast_pool_allocator<CustomObject>;
    

    Example

    #include <boost/unordered_set.hpp>
    #include <boost/pool/pool.hpp>
    #include <boost/pool/pool_alloc.hpp>
    
    struct CustomObject {
        CustomObject(std::size_t value)
            : value(value)
        {
        }
    
        std::size_t value;
    };
    
    struct CustomObjectKeyEq {
        bool operator()(CustomObject const& l, CustomObject const& r) const 
        {
            return l.value == r.value;
        }
    };
    
    std::size_t hash_value(CustomObject const& value)
    {
        return value.value;
    }
    
    int main()
    {
        typedef boost::unordered_set<CustomObject,
                                     boost::hash<CustomObject>,
                                     CustomObjectKeyEq> StandardObjectSet;
    
        StandardObjectSet set1;
        set1.insert(10);
        set1.insert(20);
        set1.insert(30);
    
        using fast_allocator = boost::fast_pool_allocator<CustomObject>;
        typedef boost::unordered_set<CustomObject,
                                     boost::hash<CustomObject>,
                                     CustomObjectKeyEq,
                                     fast_allocator> CustomObjectSet;
    
        CustomObjectSet set2;
        set2.insert(10);
        set2.insert(20);
        set2.insert(30);
    
        return 0;
    }
    

    Question 2: Does this increase the speed of my program?

    Generally, you must measure it. It has no significant impact on example above. Inserting one million object into set1 took:

    0.588423s wall, 0.570000s user + 0.020000s system = 0.590000s CPU (100.3%)

    and into set2:

    0.584661s wall, 0.560000s user + 0.010000s system = 0.570000s CPU (97.5%) 1000000