Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2000-01-29 15:41:31


From: Mark Borgerding <mborgerding_at_[hidden]>
> I dug a little deeper into the performance difference between shared_ptr
> and linked_ptr.
>
> It seems that the major difference is due to the fact that the default
> constructor for shared_ptr allocates a long on the heap (I didn't realize
> it did that).
>
> In my original test, which tested copy construction,assignment and default
> construction operations with equal frequency, linked_ptr won hands down.
> However, upon closer examination, it looks like shared_ptr is actually
> faster in 2 out of 3 of those operations. I tested the operations
> separately and recorded the following times for 10E6 iterations.
>
> linked_ptr
> ass't : 1.321 s
> copy : 1.24 s
> void c'tor : 2.299 s
> shared_ptr
> ass't : 0.251 s
> copy : 0.645 s
> void c'tor : 16.036 s

So it will take only two copies or assigns to pay for constructing
one linked_ptr, but will take some 20 to 50 copies or assigns to
pay for constructing a shared pointer?

> This stresses a few points:
> 1) heap allocations are slow

Allocators vary a lot, and the default is often lousy. The one you
are measuring seems particularly bad.

It may be worth customizing the count allocation for shared_ptr.

It may be worth having a high performance allocator for boost.

> 2) It is generally impossible to say X is better/faster than Y without
> knowing how X or Y will be used.

True.

> 3) I should really do my homework before posting performance

What you posted was fine -- but as always, more will be revealed.

> By the way, I changed around a few things in linked_ptr.hpp in order to get
> g++ to inline some functions. I would post it now, but it's pretty hacked
> up. I will distribute later (tomorrow?).
>
> On the topic of what position, if any, linked_ptr should take in boost.
> I think it could serve as a replacement for shared_ptr in most respects.

Yes. I'd like to see us keep tweaking and measuring. If the performance of
the linked version can be made more or less equivalent to the counted version
then it might be worth switching implementations.

If the performance cannot be made equivalent, and there are clear advantages
and disadvantages for both approaches, then it might be worth providing
both.

> The only reason I would suggest having both linked_ptr and shared_ptr
> concurrently is the object size. The linked_ptr class has one more pointer
> shared_ptr, increasing its object size by 50% (the heap allocation somewhat
> offsets the total memory used) So I guess I could see the case for both
> classes if the memory footprint of the smart pointer was really important.
> But in that case, I would suggest making a smart pointer class that had a
> pointer to a struct, instead of a T* and long*. The struct would contain
> both those items. This would reduce the size of the smart pointer object
> to a single pointer, the same as if it were a dumb pointer -- pretty cool
> IMO.

I have tried this before. I found no measurable performance advantage or
disadvantage, and I don't know how to make it work with multiple inheritance.

> Other thoughts:
> I thought about implementing a release() function that would allow the
> class user to take responsibility for cleaning up a pointer. Any thoughts?
> I was thinking that the message would be passed along to the neighbors
> during the reset() (delay the work until it is necessary.)
>
> Is there a reason shared_ptr does not have a release()?

Because it could leave all the other shared_ptrs dangling?


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