Boost logo

Boost :

Subject: Re: [boost] [function] function wrapping with noexceptionsafetyguarantee
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2010-11-02 18:38:10


On Sat, Oct 30, 2010 at 1:24 PM, Domagoj Saric <dsaritz_at_[hidden]> wrote:
>
> "Daniel Walker" <daniel.j.walker_at_[hidden]> wrote in message
> news:AANLkTimSdhEy=bQxj=mKkJG0d48kuCpXYnQz9DK2O_A0_at_mail.gmail.com...
>
>> So, I think the current boost::function implementation is certainly
>> the right default, since many users would not appreciate doubling the
>> static space overhead for a time savings of less than 10% per call.
>
> I already explained to you that there is no 'double space overhead' with the
> condition that the change is done right or the linker is able to merge
> identical objects, neither of which is true in the case you posted.

I'll try to give a brief outline to illustrate why adding a static
vtable means there are at least two static vtables per signature. Here
is what boost::function must do when you assign a target:

static target_type stored_vtable = // target function vtable
if(assign(stored_vtable, target_function)) // clone the function
    vtable = &stored_vtable;
else
    vtable = NULL;

Now, if instead we want vtable to point to a static empty object, we
need to do something like the following.

static target_type stored_vtable = // target function vtable
if(assign(stored_vtable, target_function)) // clone the function
    vtable = &stored_vtable;
else {
   static empty_target_type stored_empty_vtable = // empty target vtable
   assign(stored_empty_vtable, empty_function) // does not fail
   vtable = stored_empty_vtable;
}

Again this is a rough outline of boost::function assignment, but it
gives you the idea. The reason you need two static initializations is
that target_type and empty_target_type may not be the same type.

> The 'double' overhead you got is actually not 'double' but one unnecessary
> vtable extra:
> - even in your implementation, if you assigned more (different typed)
> targets to a boost::function you'd get an additional vtable for each of
> those (different typed) targets...so the overhead, as said, is not double
> but one extra...

In the worst case scenario one extra vtable per signature _is_ double;
i.e. in the worst case, the largest increase in overhead you can
possibly see is 100%. I do not mean that there are at most two
vtables; I mean there are at least two vtables instead of one.

> - the problem with your implementation is that you copied the original
> assign() member function for your new "empty target" function copying with
> it the local static vtable...to do it right the vtable must not be a local
> (template) function static...

It doesn't matter whether the empty static assignment is in a
different member function or not. boost::function will still require
two static assignments: one for the actual target and one for the
empty target.

>
> Not to mention, as also already explained in more detail (and pointed to by
> Nevin), this 'overhead' of a few static pointers is completely insignificant
> compared to various related code bloat issues...

On some platforms the overhead of a few static pointers matters a
great deal. Regardless, there's no reason to increase the static space
overhead at all, if it does not improve time performance
commensurately.

Daniel Walker


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