Boost logo

Boost :

From: William Kempf (sirwillard_at_[hidden])
Date: 2000-11-27 10:30:43


--- In boost_at_[hidden], Kevlin Henney <kevlin_at_c...> wrote:
> In message <200011232346.PAA22491_at_m...>, Jesse Jones
> <jesjones_at_h...> writes
> >My callback usage almost always looks something like this:
> >
> > mPushButton = new PushButton(...);
> >
> > boost::callback<void> callback(this, &MyObject::OnClicked);
> > mPushButton->SetNotifier(callback);
> >
> >This pretty much mandates at least one copy. It's true that I
don't
> >*need* to have callbacks be copyable, but if they're not I think
I'll
> >always be wrapping them up with shared_ptr which seems silly.

If SetNotifier were templated to take a functor reference instead of
a callback you'd eliminate the copy. Personally, I'd almost always
prefer using "callback" only in the internals in order to be able to
store varied types of functors for later calling. Client code would
never touch callbacks directly.

> I don't see the need for any reference counting in this at all,
which I
> think demonstrates the point I was getting at. The context you've
used
> above is that of a GUI framework, where the effect of reference
counting
> such objects is, at best, going to be a drop in the ocean :-}

In other words, you're not following the 80/20 rule and are applying
optimizations that take more effort than the result warrants.
 
> Also don't forget that shared_ptr allocates two objects, so in
theory
> you couldn't recover any ROI until your second copy anyway.

Help me. I've not heard the acronym ROI.

In any event, the cost of copying is MUCH more than the number of
allocations that must be made. Not to mention that for all we know,
the ref-counted object may do a thousand allocations internally when
you copy it. Even with out knowing precisely what ROI means, it
doesn't sound like you can theorize anything here.

> Also note
> that the footprint (single pointer) and working set (single heap
object
> with vptr + sizeof(funcobj)) of a cloning version is lower than
that of
> the detached reference-counted version. [Aside: This would be
different
> for countable_ptr, http://www.boost.org/more/count_bdy.htm, which I
must
> get round to Boostifying at some point.]

This *may* be important. It all depends on whether speed or size are
more important to your optimizations. Even your countable_ptr must
pay attention to this, because there's still an additional integral
type for the ref-count involved.
 
> More generally, there is a general trend away from hidden body
reference
> counting as an optimisation as it has proved to be awkward and not
> always an optimisation. For instance, the standard basic_string
makes
> effective reference counting awkward, and often a waste of effort.

The reasons why don't apply here, however. They are hardly universal
reasons. For one thing, basic_string implementations have to be COW
not just RC. The COW attribute can result in performance actually
degrading for some uses. Further, COW causes some tricky situations
with iterators and similar functionality of basic_string that really
only apply to a few class types. None of this applies here.

> And
> then there's multithreading.

This is the real wart on the idiom. I know that RC has been used
successfully in some MT situations, but I'm not familiar enough with
this particular case (I've avoided it for good reasons) to know if a
general solution can be applied. Regardless, it's difficult and
error prone even in those situations where I know it can be used.

> IIRC, the next (or even current) version of
> Dinkumware has dropped reference counting, and SGI doesn't use it at
> all. I don't see a technical reason to buck this trend and plenty of
> technical reasons to follow it.

For basic_string I'd have to agree. In general, I'm not as sure.

Bill Kempf


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk