
On Tue, May 13, 2008 at 11:11 PM, Marco Costalba <mcostalba@gmail.com> wrote:
On Tue, May 13, 2008 at 9:32 PM, Giovanni Piero Deretta <gpderetta@gmail.com> wrote:
// adding all overloads, If I can get it my way :) struct foo_fwd { template<typename T> void operator()(T x) { foo(x); } };
my_msf f = foo_fwd(); //sizeof(f) = O( sizeof(boost::function) )
Comments? Did I convince you? ;)
Yes ;-) I'll stick to one_copy_only behaviour for set_all()
But because to implement the N copy case is trivially simple (much simpler then your example) I would like to change the signature of set_all in the following way
template<typename Fun> void set_all(Fun const& fun, bool multi_instance = false);
Regarding the sizeof(f) == O( sizeof(boost::function) * N ) problem, given that
- boost::function object are member data, so allocated on the stack
Hum. I'have used vectors of boost::function objects. Those are definitely not allocated on the stack, and when you have many of them, size starts to matter, and for many signatures the size difference is significant. I do not think this usage is exceptional, in fact boost::signals does exactly that as it keeps a list of boost::functions as callback. I intend to use MSF as a replacement for boost::function, and I will definitely use vectors of MSF.
- boost::function object are created at MSF instantation (seldom event or not in critical loop context?), not during assignment (more often event, more performance critical ? )
Copyng N boost::function objects will require N indirect function calls instead of one for the straight forward implementation. Probably it is not likely to be a bottleneck, but I would not like to pay for what I do not use. The implementation seems needlessly complex :) Also, the extra complexity in the implementation might (or might not) have an effect on compile time.
I would like to know if
- boost::function default c'tor does some allocation? An empty boost::function is cheap to create ?
You can assume so.
- When a functor is assigned by reference with boost::ref boost::function just copies a pointer/reference ?
Since boost-1.34, It should no longer require dynamic memory allocation (due to small object optimization), but that is not guaranteed. Also there will be hard for the compiler to optimize away all the indirect function calls required to copy the stored object. In general a non empty boost::function construction and copy imply a memory allocation.
If the above it's true, but I am not an expert of boost::function, the problem of allocation of N boost::function perhaps is more theoretical then real, also the size problem, given that boost::function requires just 3 pointers does not seem a biggie IMHO.
Well. You can implement msf with just two pointers: one to the virtual table (which is per signature set and not per instance) and one to the actual (heap allocated functor). I think that boost::function has space for an extra pointer so that bound member functions can benefit from SOO, thus sizeof(boost::function) is (usually) sizeof(void*)*3. Your implementation uses at least sizeof(void*) * 3 * N, where N is the number of signatures. In addition I think it requirs an extra pointer to point to the function object. This is very, very wasteful: if you have a vector of msf even of moderate size, the multiplier might be the difference between fitting and not fitting in the cache. Larger stack might also be a problem for threaded programming. In addition you have to consider the N indirect calls you have to do for each copy, comparision etc...
BTW remember the resul_of implementation request? [...] It is very simple, I even don't believe it can work...but it does :-)
Great! :) -- gpd