Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2006-01-09 11:55:55


Douglas Gregor wrote:
> On Jan 9, 2006, at 10:13 AM, Peter Dimov wrote:
>
>> Douglas Gregor wrote:
>>> On Jan 9, 2006, at 7:18 AM, Peter Dimov wrote:
>>>
>>>> Even if I did, bind(&X::f, &x, _1, true) would still overflow the
>>>> 12 byte buffer. ;-)
>>>
>>> Why? Does it need more than the 8-byte member pointer and 4-byte
>>> pointer?
>>
>> The 'true' needs to be stored somewhere.
>
> *Smacks forehead*
> I didn't see the true, because I was assuming that you had written
> bind(&X::f, &x, _1) :)
>
> Anyway, we're going to have a cutoff somewhere, The curse of the SBO
> is that at some point your objects don't fit into the small buffer
> any more, so you have a jump in your performance curve.

Yes. It would be interesting to measure the performance for larger buffer
sizes, though. The break-even point should occur somewhere around 32 or 48,
maybe even 64 if the allocator is bad enough.

> If we go to 16 bytes, then bind(&X::f, &x, _1, true) will fit but
> bind(&X::f, &x,
> _1, true, true) won't.

It probably will unless 'true' is 4 bytes.

> The member pointer + "this" pointer case seems
> like the one that users would most expect to work well. It goes head-
> to-head with delegates, closures, and other similar extensions, with
> the added benefit of keeping boost::function down to 16 bytes. It
> just feels like the right cutoff for the buffer size.

In my experience, the closure case is indeed very common in code written by
people who don't take advantage of the full expressive power of boost::bind,
probably because they have a Borland/delegate background. If you design your
class to have

struct X
{
    void show();
    void hide();
};

closures are enough. But there is an alternative. You can use

struct X
{
    void set_visibility( bool visible );
};

and synthesize show/hide with boost::bind. My code tends towards the latter
variety, so I won't be seeing much of the SBO with a &X::f+&x cutoff.

BTW, this talk about 12 byte buffer is assuming g++. A member pointer is
4-16 on MSVC, 8 on g++, 12 on Borland, 4 on Digital Mars (!). There's a nice
table in

http://www.codeproject.com/cpp/FastDelegate.asp

Anyway, I committed a storage optimization to the CVS. <crosses fingers>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk