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).
3 回答
关于这种可能性有很多争论,最终提出的至少一个建议版本auto_ptr
是针对引用计数的 COW 指针。
不幸的是,COW 的时代已经过去了。使 COW 指针(或 COW-whatever)线程安全会引入严重的性能问题。
编辑:重读一遍,我觉得有必要指出并非所有对 COW 的使用都必然过时。有时它仍然有意义。线程安全增量的开销几乎是固定的——所以这只是一个对象必须有多大的问题,或者复制它的成本有多高,COW 才有意义。也有时间/地方你有很多(未修改的)对象的副本,内存的节省可以是一个合理的权衡——内存的节省证明了一些额外的处理器时间是合理的。如果您可以将分页数据保存到磁盘或从磁盘保存一些数据,您就可以快速出局。
就像 Jerry Coffin 所说的那样,已经证明 COW 习语引入了性能问题……但实际上还有另一个问题。
实际编写 COW 的通用实现是不可能的(如您链接到的文章所示)。在 COW 实现中std::string
,只要调用将实际修改字符串状态的操作,就会执行 Copy。但是,指针应该如何知道呢?它不知道它指向的类。
例如,假设我这样做:
void method(Foo& foo, flag_t flag)
{
if (flag == flag::Yes) foo.modify();
}
void invoke(COWPointer<Foo> ptr)
{
method(*ptr, flag::No);
}
哎呀!Foo
即使它不会被修改,我也会复制该对象!
问题是,虽然这个 COW 类有帮助,但实际上你必须包装它:
class Foo
{
public:
private:
COWPointer<FooImpl> mImpl;
};
然后真正修改对象的 Foo 方法将负责复制FooImpl
状态。所以当然课程会有所帮助,但它也不是灵丹妙药。
而所有这些麻烦......由于 MT 应用程序中的同步问题,无法确定实际获得性能......
尽可能避免复制(使用引用/指针)而不是在某些情况下调整您的类以获得可能的收益,这会惩罚已经处理过性能问题的用户,这不是更简单吗?
“指针”和“写入时复制”之间存在矛盾:根据定义,取消引用指针不会改变它,而改变*p
不会改变p
。
因此可以取消引用 const 指针,并且可以修改生成的左值。
您实际上是在谈论单元素容器,而不是指针。