Flyweight design pattern with C++11

To optimize the memory consumtion of the Minko engine, we started by profiling the memory allocations using tools such as the integrated Visual Studio 2013 memory profiler or Massif.

One of the heaviest source of memory allocations was for  std::string  objects. It’s not really a surprising considering one of Minko’s biggest feature is dynamic data binding between the engine data – on the CPU – and the shader data – on the GPU. And “dynamic” means we have to create those bindings according to some naming conventions and explicit declarations made in “effect” files using JSON. Read: we use lots of strings.

We use strings for material property names, but also for the camera properties or the geometry vertex attribute names. It makes the engine very flexible and extensible while keeping some important aspects of strict typing using templates. But it uses a lot of memory because each property names is stored multiple times.

Materials for example are highly likely to share most (if not all) of their property names. If you have 10 of those materials, the property name strings will use 10 times too much memory.

To solve this, I’ve implemented the flyweight design pattern.

It was very easy to do thanks to the unordered_set STL container and especially the behavior of the “insert” method which gives us a direct access to the corresponding inserted or pre-existing element pointer:

 There are a few insteresting things:

  • the move constructor is here to make sure that creating  Flyweight<T>  from a  T  rvalue should not make any copies;
  • thanks to variadic templates, the forward constructor should allow the implicit conversion from any  T  constructor, for example you a  Flyweight<std::string>  will be implicitely created when using a string literal;
  • the move assignment operator should make manipulations of Flyweight-based containers more efficient;
  • the templated cast T operator override should allow  Flyweight<T>  to  T  implicit conversions.

Thanks to the forward constructor and the templated cast operator, you can easily change the type of any  T  by  Flyweight<T>  without modifying much of the actual implementation – if at all!

The Flyweight class will soon be in Minko on github.