C++ Optimization – Dependency Injection vs Memory Usage

cdependency-injectionmemory usageoptimization

I have a hypothetical C++ code containing these two classes:

  • Master: it's big, does a lot of things and is meant to have only one instance;
  • Slave: quite the opposite. It can also do a lot of things, but it's small, and has many instances.

Every slave needs access to the master, so it is injected through the constructor:

class Slave {
    private:
        // Few small attributes
        Master& master;
    public:
        Slave(Master& master) master(master) { }
        // May have lots of methods...
}

As there are many slaves, each one holding a reference to the master, a lot of memory is wasted in pointers that point to the same thing. I would like to think that the C++ compilers could find a way to optimize that Master& master attribute out of the Slave class, but I don't believe they do it – please, correct me if I'm wrong.

A solution would be to turn the Master class into a Singleton, but that is widely considered an anti-pattern. I think maybe a better approach is to turn the Master& master attribute into a static pointer:

class Slave {
    private:
        // Attributes...
    public:
        static Master* master;
        Slave() { }
        // Methods...
}

It's a pity that the reference needs to be converted to a pointer, but at least this eliminates the memory waste, while preserving the ability to "inject" the master and using a mock for testing.

What do you guys think?

Best Answer

Well you're right about something being wrong. But I highly doubt worrying about memory usage is going to fix it.

Unless you can point to some real world data that shows you have a memory problem at the scale of these references, I wouldn't worry about it. This smacks of premature optimization.

Now that doesn't mean there aren't problems here. The master is forcing the slaves to depend on parts of it that they don't need. That's a violation of the interface segregation principle. If I don't need it then keep it away from me.

The slaves deserve to make their dependencies explicit. That doesn't mean they can only take primitives (see primitive obsession). They could take a parameter object of their own. But those parameter objects should be tailored to the individual needs of the slaves. Not a one size fits all.

Worry about memory after you've freed your slaves.