In my Januray post, I focused on implementing a singleton correctly. This time I want to add performance into the mix and show you the best way to implement your singleton... or give you guidance to pick your best way.
Setting the scene
I'm using a display manager as an example, like GDM, LightDM, or others in the Linux world. Here is the motivating implementation for today:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 A enum class Resolution { r640x480 , r800x600 , // ... }; B class DisplayManager { Resolution mResolution {}; C DisplayManager ( const DisplayManager & ) = default ; DisplayManager ( DisplayManager && ) = default ; DisplayManager & operator = ( const DisplayManager & ) = default ; DisplayManager & operator = ( DisplayManager && ) = default ; DisplayManager () = default ; D public : static DisplayManager & Instance () noexcept { static DisplayManager dspm {}; E return dspm ; } void SetResolution ( Resolution newRes ) { mResolution = newRes ; } Resolution GetResolution () const { return mResolution ; } };
Let me quickly go through the various parts. In A, you see the data type Resolution which illustrates two resolutions; you can imagine the rest. Next in B, you find the DisplayManger implementation. Diving into the implementation, you can see that I used my own advice from my last post and made the copy- and move-operations private in C. This is all just setup for today's focus.
To complete the picture, here is how I use the object:
1 2 3 4 5 6 7 Resolution Use () { auto & s = DisplayManager :: Instance (); s . SetResolution ( Resolution :: r640x480 ); return s . GetResolution (); }
Let's talk performance
Going back to the DisplayManager implementation, the interesting part starts with D, the default constructor, which of course must be private in a singleton. More on that in a moment. As a last item, you see E, where I use a block local static for the variable dspm .
Let's talk performance. With C and D we have two places where we can use different implementations that influence performance for DisplayManager objects, or better access. But you might not always have the full freedom to pick all the options.
... continue reading