Jordan Savant # Software Engineer

Pooling

The object pool pattern is a software creational design pattern that uses a set of initialized objects kept ready to use, rather than allocating and destroying them on demand.

Object pooling can offer a significant performance boost in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instances in use at any one time is low.

In game development, allocating objects on the heap during run time is an expensive operation and can remove the entire cost of mid-game allocation by pooling objects up front.

C++ Implementation of Object Pooling

This following illustrates a template based object pool. It will create objects as requests exceed size using either the default constructor of the class or a factory method passed in through functional programming.

Objects are also expected to implement a "reset" method so that the object can be returned to sane values before passing back to requesting operations.

#!c++
#include <vector>
#include <functional>

template<class T>
class Pool
{
public:
    Pool()
        : maximumCreated(0), factoryMethod(NULL)
    {
    }

    Pool(int count)
        : maximumCreated(0), factoryMethod(NULL)
    {
        add(count);
    }

    Pool(int count, std::function<T*(void)> factoryMethod)
        : maximumCreated(0), factoryMethod(factoryMethod)
    {
        add(count);
    }

    ~Pool()
    {
        for(unsigned int i = 0; i < pool.size(); i++)
        {
            delete pool[i];
        }
    }

    std::vector<T*> pool;
    unsigned int maximumCreated;
    std::function<T*(void)> factoryMethod;

    void add(int count)
    {
        for(int i = 0; i < count; i++)
        {
            T* ob = create();
            pool.push_back(ob);
            maximumCreated = std::max((unsigned int)maximumCreated, (unsigned int)pool.size());
        }
    }

    T* fetch()
    {
        T* ob = NULL;

        if(pool.size() > 0)
        {
            ob = pool.back();
            pool.pop_back();
        }
        else
        {
            ob = create();
        }

        return ob;
    }

    void recycle(T* ob)
    {
        ob->reset();
        pool.push_back(ob);
        maximumCreated = std::max((unsigned int)maximumCreated, (unsigned int)pool.size());
    }

    T* create()
    {
        if(factoryMethod)
            return factoryMethod();
        else
            return new T();
    }
};