
On Sat, Oct 30, 2010 at 1:24 PM, Domagoj Saric <dsaritz@gmail.com> wrote:
"Daniel Walker" <daniel.j.walker@gmail.com> wrote in message news:AANLkTimSdhEy=bQxj=mKkJG0d48kuCpXYnQz9DK2O_A0@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