Currently with the library I have written, my small objects (which are not polymorphic) are allocated, within an object-pool, in a vector with unique_ptr‘s. Now obviously I want to change this because there’s obviously a lot of over-head in calling new so many times. I’m curious if it is more efficient to: cache the objects in the pool (store it in a vector, i.e. vector<Object>), or create the object when it is needed, via it’s ID. And note that there is a lot of objects that are created.
What I mean is, should I be doing this:
Create the object when needed? (Note these objects are small, 64-128 bits, as all is contained is an ID and a reference/pointer to a parent object)
Object ObjectFactory::create()
{
return Object(nextId(), getParent());
}
Object ObjectFactory::get(unsigned id)
{
return Object(id, getParent());
}
or:
Object& ObjectFactory::create()
{
// get the next id of the object
unsigned id = nextId();
// resize (if necessary)
if(_objects.size() <= id)
{
_objects.resize(id + 1);
_objects[id]._parent = getParent();
}
return _objects[id];
}
Object& ObjectFactory::get(unsigned id)
{ return _objects[id]; }
What I’m specifically concerned about is: would the re-creation of the Object‘s cause much over-head?
@LokiAstari is right, you clearly have a problem with your pointers on resize.
There’s something I don’t understand; you say you’re using an object pool but that you have problems with too many new statements. If you’re using an object pool, I would say it’s precisely to avoid new statements, no?
Here are my suggestions, although I’m no expert and there might be better solutions involving the implementation of your own allocator typically (dark side of the force..). You could use a container like
std::deque, which ensures the validity of pointers/references on resize.You would begin with an initial resize of a lot of Objects (your pool), and you can either handle manually the subsequent resize when needed (extending the capacity with chunks of predefined size), or accept the new statements then if you know there shouldn’t be a lot, and use the emplace_back method.
I also don’t know if you’re doing a lot of insertion/deletion of objects with your IDs. If so, you might consider using
std::unordered_map.Here is an example using
std::deque: