$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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