
On Sat, Nov 6, 2010 at 2:08 PM, Emil Dotchevski <emil@revergestudios.com> wrote:
On Sat, Nov 6, 2010 at 10:22 AM, Daniel Walker <daniel.j.walker@gmail.com> wrote:
On Tue, Nov 2, 2010 at 7:20 PM, Jeffrey Lee Hellrung, Jr. <jhellrung@ucla.edu> wrote:
On 11/02/2010 02:50 PM, Daniel Walker wrote: [...]
Here are the results I got, again, using the build of g++ 4.2 provided by my manufacturer.
Data (Release): | function | function (static empty) time/call | 3.54e-07s | 3.51e-07s space/type | 64B | 80B
Data (Debug): | function | function (static empty) time/call | 2.05e-06s | 2.04e-06s space/type | 64B | 80B
You can see that removing the empty check from boost::function yields about a 1% improvement in time per call to boost::signal. The increased space per type overhead is the same as before: 16B.
[...]
[Butting in after only vaguely following this thread...]
Would it also be appropriate to measure the "space/call", in addition to "time/call" and "space/type"? Or is there no difference, or had this been addressed already?
Well, a call to boost::function does not cost any additional space. However, there is a space/object cost, which the other benchmark does measure. The space overhead per boost::function object is constant. On my machine it's 32B for both of the empty state schemes.
Can someone please explain why does storing the empty state take space per type?
Storing a target function takes space per type, namely, the static stored_vtable on line 912 of boost/function/function_template.hpp, which is dependent on both the type of boost::funciton's signature and the type of the target function. If the empty state is represented by a special "empty" target function, then this requires space to store the "empty" target function. We can move around where that space is consumed: it could be in the writable, initialized static data section, or we could move it to constant static data in the text segment. Regardless, the empty state must be either represented using memory or computed dynamically. As they say, there's no such thing as a free lunch. If boost::function is going to have two states, then those two states come at a cost. We can pay for them with either an extra static vtable in the executable or an extra pointer comparison, which in many cases can be optimized away by the compiler. The exact expense depends on the user's circumstance, which is why I think users should have the option to choose between the two schemes. Daniel Walker