|
Boost Users : |
Subject: [Boost-users] [bind][function] Do copy constructors invoked inside boost::bind / boost::function get optimized out?
From: Steve Lorimer (steve.lorimer_at_[hidden])
Date: 2010-07-26 18:05:45
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 <boost/intrusive_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
using namespace std;
struct ref_ctd
{
int refs;
ref_ctd() : refs(0) { }
};
template<typename T>
void intrusive_ptr_add_ref(T* p)
{
cout << "++ setting p (" << p << ")'s refs to " << p->refs + 1 << endl;
++p->refs;
}
template<typename T>
void intrusive_ptr_release(T* p)
{
cout << "-- setting p (" << p << ")'s refs to " << p->refs - 1 << endl;
if (!--p->refs)
delete p;
}
struct foo : public ref_ctd
{
void func(char a) { cout << a << endl; }
};
void bar(boost::intrusive_ptr<foo> f)
{
f->func('b');
}
int main()
{
cout << "--------- creating intrusive ptr ----------" << endl;
boost::intrusive_ptr<foo> f(new foo);
cout << "--------- binding intrusive_ptr object ----------" << endl;
boost::bind(&foo::func, f, 'a');
cout << "--------- now storing result of bind ----------" << endl;
boost::function<void()> func1 = boost::bind(&foo::func, f, 'a');
cout << "--------- binding intrusive_ptr object ----------" << endl;
boost::bind(bar, f);
cout << "--------- now storing result of bind ----------" << endl;
boost::function<void()> func2 = boost::bind(bar, f);
return 0;
}
Here are the results:
--------- creating intrusive ptr ----------
++ setting p (0x33b18)'s refs to 1
--------- binding intrusive_ptr object ----------
++ setting p (0x33b18)'s refs to 2
++ setting p (0x33b18)'s refs to 3
++ setting p (0x33b18)'s refs to 4
++ setting p (0x33b18)'s refs to 5
++ setting p (0x33b18)'s refs to 6
-- setting p (0x33b18)'s refs to 5
-- setting p (0x33b18)'s refs to 4
++ setting p (0x33b18)'s refs to 5
-- setting p (0x33b18)'s refs to 4
-- setting p (0x33b18)'s refs to 3
-- setting p (0x33b18)'s refs to 2
-- setting p (0x33b18)'s refs to 1
--------- now storing result of bind ----------
++ setting p (0x33b18)'s refs to 2
++ setting p (0x33b18)'s refs to 3
++ setting p (0x33b18)'s refs to 4
++ setting p (0x33b18)'s refs to 5
++ setting p (0x33b18)'s refs to 6
-- setting p (0x33b18)'s refs to 5
-- setting p (0x33b18)'s refs to 4
++ setting p (0x33b18)'s refs to 5
-- setting p (0x33b18)'s refs to 4
-- setting p (0x33b18)'s refs to 3
++ setting p (0x33b18)'s refs to 4
++ setting p (0x33b18)'s refs to 5
++ setting p (0x33b18)'s refs to 6
++ setting p (0x33b18)'s refs to 7
++ setting p (0x33b18)'s refs to 8
++ setting p (0x33b18)'s refs to 9
-- setting p (0x33b18)'s refs to 8
-- setting p (0x33b18)'s refs to 7
-- setting p (0x33b18)'s refs to 6
-- setting p (0x33b18)'s refs to 5
-- setting p (0x33b18)'s refs to 4
-- setting p (0x33b18)'s refs to 3
-- setting p (0x33b18)'s refs to 2
--------- binding intrusive_ptr object ----------
++ setting p (0x33b18)'s refs to 3
++ setting p (0x33b18)'s refs to 4
++ setting p (0x33b18)'s refs to 5
++ setting p (0x33b18)'s refs to 6
-- setting p (0x33b18)'s refs to 5
++ setting p (0x33b18)'s refs to 6
-- setting p (0x33b18)'s refs to 5
-- setting p (0x33b18)'s refs to 4
-- setting p (0x33b18)'s refs to 3
-- setting p (0x33b18)'s refs to 2
--------- now storing result of bind ----------
++ setting p (0x33b18)'s refs to 3
++ setting p (0x33b18)'s refs to 4
++ setting p (0x33b18)'s refs to 5
++ setting p (0x33b18)'s refs to 6
-- setting p (0x33b18)'s refs to 5
++ setting p (0x33b18)'s refs to 6
-- setting p (0x33b18)'s refs to 5
-- setting p (0x33b18)'s refs to 4
++ setting p (0x33b18)'s refs to 5
++ setting p (0x33b18)'s refs to 6
++ setting p (0x33b18)'s refs to 7
++ setting p (0x33b18)'s refs to 8
++ setting p (0x33b18)'s refs to 9
++ setting p (0x33b18)'s refs to 10
-- setting p (0x33b18)'s refs to 9
-- setting p (0x33b18)'s refs to 8
-- setting p (0x33b18)'s refs to 7
-- setting p (0x33b18)'s refs to 6
-- setting p (0x33b18)'s refs to 5
-- setting p (0x33b18)'s refs to 4
-- setting p (0x33b18)'s refs to 3
-- setting p (0x33b18)'s refs to 2
-- setting p (0x33b18)'s refs to 1
-- setting p (0x33b18)'s refs to 0
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net