[bind][function] Do copy constructors invoked inside boost::bind / boost::function get optimized out?

Hi
I'm using boost::bind to convert a function of the form:
T::fun(boost::intrusive_ptr<U>) into a form which can be stored by
boost::function.
Outputting calls to intrusive_ptr_add_ref and intrusive_ptr_release reveals
there are a massive number of copies of the intrusive_ptr. For a single call
of boost::bind on a
I'm wondering what kind of overhead this will add if I'm calling boost::bind
on boost::intrusive_ptr a LOT of times? Will the copies be optimized out?
There are 6 calls to intrusive_ptr_add_ref when calling boost::bind to bind
a member function pointer to an object which is wrapped up in an
intrusive_ptr
There are 5 calls to intrusive_ptr_add_ref when calling boost::bind to bind
an argument which is an intrusive_ptr
There are 12 calls to intrusive_ptr_add_ref when using boost::function to
store the result of boost::bind when called to bind a member function
pointer to an object which is wrapped up in an intrusive_ptr
There are 11 calls to intrusive_ptr_add_ref when using boost::function to
store the result of boost::bind when called to bind an argument which is an
intrusive_ptr
Example code and output showing the calls below:
#include <iostream>
#include

On Mon, Jul 26, 2010 at 3:05 PM, Steve Lorimer
I'm using boost::bind to convert a function of the form: T::fun(boost::intrusive_ptr<U>) into a form which can be stored by boost::function. Outputting calls to intrusive_ptr_add_ref and intrusive_ptr_release reveals there are a massive number of copies of the intrusive_ptr.
By design, boost::bind copies the objects it's passed. The refcounts can't be optimized out because they are a result of making actual copies. If you want boost::bind to only keep a reference to the objects you're passing to it, use boost::ref or boost::cref. For example, instead of bind(foo,a) use bind(foo,ref(a)). HTH Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

[quote]
If you want boost::bind to only keep a reference to the objects you're passing to it, use boost::ref or boost::cref. For example, instead of bind(foo,a) use bind(foo,ref(a)).
[/quote] No, I want the object to be reference counted - and am aware that internally bind has to make copies. However, I expected at least one, perhaps two or three copies to be made. 10 copies made for a single call to bind seems really expensive. I'm asking more about whether the optimizer is able to optimize out several of these copies, or if it's overhead that one has to accept if one wants to use bind and/or function? I haven't tested it yet, but I imagine a call to bind with more arguments will involve a lot more copying, as bind looks something like this for argument lists internally: template< class A1 , class A2 , class A3 , class A4 > class list4: private storage4< A1 , A2 , A3 , A4 > template< class A1 , class A2 , class A3 , class A4 > struct storage4 : public storage3< A1 , A2 , A3 > template< class A1 , class A2 , class A3 > struct storage3 : public storage2< A1 , A2 > template< class A1 , class A2 > struct storage2 : public storage1< A1 > template< class A1 > struct storage1 Argument A1 is copied for each constructor in the list as it's passed down the inheritance hierarchy. Are there plans to implement bind using variadic templates? Not sure if that would reduce the number of copies? TIA Steve

Le 27/07/2010 06:34, Steve Lorimer wrote:
No, I want the object to be reference counted - and am aware that internally bind has to make copies. However, I expected at least one, perhaps two or three copies to be made. 10 copies made for a single call to bind seems really expensive.
According to your earlier test, that's 6, not 10. Could you try with boost::phoenix::bind and see if it's any different?

Steve Lorimer wrote:
I haven't tested it yet, but I imagine a call to bind with more arguments will involve a lot more copying, as bind looks something like this for argument lists internally:
template< class A1 , class A2 , class A3 , class A4 > class list4: private storage4< A1 , A2 , A3 , A4 > template< class A1 , class A2 , class A3 , class A4 > struct storage4 : public storage3< A1 , A2 , A3 > template< class A1 , class A2 , class A3 > struct storage3 : public storage2< A1 , A2 > template< class A1 , class A2 > struct storage2 : public storage1< A1
template< class A1 > struct storage1
Argument A1 is copied for each constructor in the list as it's passed down the inheritance hierarchy.
This is the optimization that makes the placeholders not occupy any space... its purpose was to allow function<> to store bind( &X::f, p, _1, _2, _3 ) without going to the heap. Unfortunately, you're right that it results in a lot more copies. Not sure what can be done here.
Are there plans to implement bind using variadic templates? Not sure if that would reduce the number of copies?
Rvalue references can help, as the copies can be converted into moves. But every compiler that has variadic templates and rvalue references also has std::bind, so there's not much point.

Thanks Peter
Am I right in saying std::bind for gcc will be based on boost's bind? If
that is the case, then there could be a point?
TIA
Steve
On 27 July 2010 11:41, Peter Dimov
Steve Lorimer wrote:
I haven't tested it yet, but I imagine a call to bind with more arguments will involve a lot more copying, as bind looks something like this for argument lists internally:
template< class A1 , class A2 , class A3 , class A4 > class list4: private storage4< A1 , A2 , A3 , A4 > template< class A1 , class A2 , class A3 , class A4 > struct storage4 : public storage3< A1 , A2 , A3 > template< class A1 , class A2 , class A3 > struct storage3 : public storage2< A1 , A2 > template< class A1 , class A2 > struct storage2 : public storage1< A1
template< class A1 > struct storage1
Argument A1 is copied for each constructor in the list as it's passed down the inheritance hierarchy.
This is the optimization that makes the placeholders not occupy any space... its purpose was to allow function<> to store bind( &X::f, p, _1, _2, _3 ) without going to the heap. Unfortunately, you're right that it results in a lot more copies. Not sure what can be done here.
Are there plans to implement bind using variadic templates? Not sure if
that would reduce the number of copies?
Rvalue references can help, as the copies can be converted into moves. But every compiler that has variadic templates and rvalue references also has std::bind, so there's not much point. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Steve Lorimer wrote:
Thanks Peter
Am I right in saying std::bind for gcc will be based on boost's bind? If that is the case, then there could be a point?
g++ already has its own std::bind; it uses variadic templates in the version I looked at (4.3.4).
participants (4)
-
Emil Dotchevski
-
Mathias Gaunard
-
Peter Dimov
-
Steve Lorimer