views:

110

answers:

2

I just saw this nice copy-on-write pointer implementation. It looks pretty generic and useful, so my question is: Is such a class contained in any of the C++ toolkits (boost, loki, etc.)? If not, I'd really like to know why because it is a really useful idiom and apparently a generic implementation seems doable (like the one I linked to).

+5  A: 

There was a lot of debate over the possibility, and at least one suggested version of what eventually came out as auto_ptr was for a reference counted COW pointer.

Unfortunately, the time for COW has mostly passed. Making a COW pointer (or COW-whatever) thread-safe can introduce serious performance problems.

Edit: Rereading that, I feel obliged to point out that not all use of COW necessarily obsolete. There are times that it still makes sense. The overhead of a thread-safe increment is pretty much fixed -- so it's only a question of how large an object has to be, or how expensive it is to copy, for COW to make sense. There are also times/places that you have lots of copies of an (unmodified) object, and the savings in memory can be a reasonable tradeoff -- the savings in memory justify some extra processor time. If you can save paging a little data to/from disk, you can come out ahead in a hurry.

Jerry Coffin
That makes me sad. :(
Frank
@Frank: Sad? How so? It just doesn't typically lead to faster code, so why use it?
jalf
A: 

Like Jerry Coffin said it's been demonstrated that the COW idiom introduced performance issues... but there is actually another issue.

It is not possible (as demonstrated in the very article you link to) to actually write a generic implementation of COW. In the COW implementation of std::string the Copy is performed whenever an operation is invoked that will actually modify the state of the string. However, how is a pointer supposed to know that ? It has no knowledge over the class it points to.

For example, let's assume I do this:

void method(Foo& foo, flag_t flag)
{
  if (flag == flag::Yes) foo.modify();
}

void invoke(COWPointer<Foo> ptr)
{
  method(*ptr, flag::No);
}

Oups! I make a copy of the Foo object even though it's not going to be modified!

The problem is that while this COW class helps, you actually has to wrap it:

class Foo
{
public:

private:
  COWPointer<FooImpl> mImpl;
};

And then methods of Foo that really modifies the object will be responsible for copying the FooImpl state. So sure the class helps, but it's not silver bullet either.

And all this trouble... without being sure of actually gaining performance because of the synchronization issues in a MT application...

Is it not simpler to actually avoid copying whenever possible (using references / pointers) rather than tweaking your class for a possible gain in some situations that will penalize users that already took care of performances issues ?

Matthieu M.