Boost logo

Boost :

From: David Maisonave (dmaisonave_at_[hidden])
Date: 2006-01-04 17:42:28


"Thorsten Ottosen" <tottosen_at_[hidden]> wrote in message
news:<dph810$l4b$1_at_[hidden]>...
> David Maisonave wrote:
> > "Thorsten Ottosen" <tottosen_at_[hidden]> wrote in message
> > news:<dpgu8s$e6k$1_at_[hidden]>...
>
> >>This gave:
> >>
> >>Test performance for initializing and copying container of pointers.
> >>
> >>vector<copy_ptr<Shape> > 1.42 s
> >>
> >>boost::ptr_vector<Shape> 0.81 s
> >>
> >>vector<cow_ptr<Shape> > 0.13 s
> >>
> >>
> >>But this test is a bit unfair: we create copies of the vector, but
> >>we never mutate that copy. A fair test would mutate all the
> >>elements.
> >
> >
> > The cow_ptr is like a clone pointer and a shared pointer put
> > together.
>
> right.
>
> > It shares the pointer, until an attempt is made to access it via
> > non-constant operator-> or operator*. If non-constant access is
> > made, then it checks to see if it's reference counter is larger then

> > one. If so, it then performs the deep-copy, and releases the
> > reference count.
> >
> > This is very efficient, because there's a good chance that the using

> > code will never access all or any of the container objects in a
> > non-constant manner.
>
> well, if no objects are being mutated, we don't have to make a copy.
>
> In practice I don't have a good estimate of how much data is touched,
> but imgaine that it can easily be it all. In that case I expect
> ptr_vector to win again (like it did in the other three categories).
>
> > The difference in efficiency will show up even more, when you have a

> > more complex type that takes more time to construct.
>
> right, the above results has another string data member of size 100.
>
> > The test code uses
> > a simple Shape class, which doesn't have much to it, but if you
> > added more data members, and made the construction more complex,
> > then the above test will be drastically different and it would show
> > cow_ptr having a very high performance ratio.
>
> it would also increase the likelihood that we would mutate the
> objects.
>
> > By the way, I believe you could add this type of COW logic to the
> > existing boost pointer containers, and increase their efficiency.
>
> It depends somewhat of the situation at hand AFAICT.
>
> > But there is an overhead to this logic,
>
> right. ptr_vector uses vector<void*> internally to minimize binary
> size too. and runtime-space-wise, its optimal. whether that matters
> depends on the situation.
>
> > and you might have notice that
> > some of the test show copy_ptr out performming cow_ptr.
> > You could consider adding a policy option to the boost pointer
> > containers, that would allow choosing between COW method and
> > Clone-Always method.
>
> perhaps, but I do fear such a thing would greatly complicate the
> implementation.
>
> I also have some concerns on performance of COW in multi-threaded
> environments.
>
> As for cow_ptr requiring copy-semantics, then I think that is a very
> poor idea. It must be possible to call new_clone() or similar.
>

I don't see anything wrong with requiring copy-semantics, and I don't
like the idea of forcing the user to implement new_clone, because it
makes using the smart pointer less generic.

The built-in types have copy constructors, and so does most of the STL
objects.
To quote Scott Meyers [Effective C++]:
************************************************************************
*****************************************************
"If it's good enough for int's, it's good enough for me and my classes.
It should be good enough for you and yours, too. Why introduce
gratuitous incompatibilities with the conventions followed by the
build-in types?"
************************************************************************
*****************************************************

A container of cow_ptr is more generic then boost pointer containers,
because it doesn't require the type to have a clone method, or extra
clone logic.
If you want to use cow_ptr with legacy code, you can do so, with out
having to break the interface.
Imagine having legacy code, in which you already have an interface for
an abstract type.
If you want to create a container of pointers using boost pointer
containers, you would have to make a lot of changes to existing legacy
code, that could, or more then likely would introduce new bugs to the
code.

It's far safer to have a container that requires little - to no
modification of existing code, and cow_ptr can do that as-is.


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