Even though most of us were taught to be generous and share whenever possible, this does not always work best in software. For example, in the world of distributed or parallel computations, shared mutable state can lead to race conditions and requires coherency protocols. But surely it doesn’t matter in the context of single-threaded execution, especially in programming languages like C++ that promise zero-cost abstractions, right?
Well, let’s find out. We’ll use construction cost as an example and compare
Nothing fancy here and since both constructors involve relatively expensive memory allocation, it would be reasonable to assume that a little extra overhead for keeping track of strong and weak references that shared pointer requires shouldn’t impact performance by much. But enough theory, let’s see what benchmark says
Ouch, looks like creating shared pointer is 2.2X slower. But why? Let’s take a look at the assembly. For unique pointer it cannot get any simpler
but for shared pointer it’s a completely different story, so I’m going to show only a small piece of its assembly below
which already makes it obvious that now we have to deal with control blocks, atomic reference counter increments etc.
So what’s the moral here? Use the simplest and most specialized tool available and if sharing is not required - don’t share :) Unique pointer is perfect for situations when there is a single owner and has the same performance as our trusty new/free friends and handily helps us to avoid memory leaks.