What is std::pair
for, why would I use it, and what benefits does boost::compressed_pair
bring?
It can sound strange to hear that compressed_pair cares about a couple of bytes. But it can actually be important when one considers where compressed_pair can be used. For example let's consider this code:
boost::function f(boost::bind(&f, _1));
It can suddenly have a big impact to use compressed_pair in cases like above. What could happen if boost::bind stores the function pointer and the place-holder _1
as members in itself or in a std::pair
in itself? Well, it could bloat up to sizeof(&f) + sizeof(_1)
. Assuming a function pointer has 8 bytes (not uncommon especially for member functions) and the placeholder has one byte (see Logan's answer for why), then we could have needed 9 bytes for the bind object. Because of aligning, this could bloat up to 12 bytes on a usual 32bit system.
boost::function
encourages its implementations to apply a small object optimization. That means that for small functors, a small buffer directly embedded in the boost::function
object is used to store the functor. For larger functors, the heap would have to be used by using operator new to get memory. Around boost version 1.34, it was decided to adopt this optimization, because it was figured one could gain some very great performance benefits.
Now, a reasonable (yet, maybe still quite small) limit for such a small buffer would be 8 bytes. That is, our quite simple bind object would not fit into the small buffer, and would require operator new to be stored. If the bind object above would use a compressed_pair
, it can actually reduce its size to 8 bytes (or 4 bytes for non-member function pointer often), because the placeholder is nothing more than an empty object.
So, what may look like just wasting a lot of thought for just only a few bytes actually can have a significant impact on performance.