user3240688
user3240688

Reputation: 1327

C++ allocator for objects whose pointers are stored in containers

I have a map<int, Foo *> where I'd need to have many inserts and erases of Foo *. Usage would look like

    map<int, Foo *> mapping;
    while(  a long time)
    {
        // make new Foo and insert into mapping
        Foo * foo = new Foo( some params)
        mapping.emplace(foo->getID(), foo);

        // sometimes we'd get an existing Foo and remove it
        if ( sometimes)
        {
            int deleteThisID = getIDToDelete();
            Foo * deleteFoo = mapping.find(deleteThisID)->second;
            mapping.erase(deleteThisID);
            delete deleteFoo;
        }
    }

I want it to be fast. I suspect the numerous calls to new and delete would be slow.

A pool allocator seems like a good option. However, my experience with allocators had all been in the context of container of objects (e.g. declare a map<int, Foo, std::allocator<std::pair<int, Foo>>>

Which is not relevant.

Should I get a pool allocator, and instead of new Foo() and delete foo, do alloc.allocate and alloc.destroy? The new code should not touch map<int, Foo *> itself, right?

Upvotes: 0

Views: 247

Answers (1)

rici
rici

Reputation: 241671

How Foo* is allocated is irrelevant to an instance of std::map<X, Foo*>, so you are correct that any change you make to improve the allocation of Foos will be isolated to that problem, and not to std::map.

Of course, std::map also does an allocation for each element (and a consequent deallocation when the element is removed), so you could also consider replacing the allocator used for the std::map to attempt to get a performance improvement. That will depend on the performance of the standard library in use, which can only be ascertained through benchmarking.

If your code is as presented and you are always deleting the element removed from the map, you could consider inserting the Foo directly into the map instead of using a pointer, which might reduce the number of allocations. Also, if you are using C++11, you might want to consider a smart pointer such as std::unique_ptr (or std::shared_ptr if you expect the same Foo* to be associated with more than one key.)

Upvotes: 1

Related Questions