Почему нет boost :: copy_on_write_ptr? - PullRequest
       27

Почему нет boost :: copy_on_write_ptr?

7 голосов
/ 28 февраля 2010

Я только что видел эту красивую указатель копирования при записи реализацию.Это выглядит довольно обобщенно и полезно, поэтому мой вопрос: содержится ли такой класс в каком-либо из наборов инструментов C ++ (boost, loki и т. Д.)?Если нет, мне бы очень хотелось знать почему, потому что это действительно полезная идиома и, по-видимому, общая реализация кажется выполнимой (как та, с которой я связан).

Ответы [ 3 ]

6 голосов
/ 28 февраля 2010

Было много споров по поводу возможности, и по крайней мере одна предложенная версия того, что в итоге получилось как auto_ptr, была для указателя COW со счетным подсчетом.

К сожалению, время для COW в основном прошло. Создание указателя COW (или COW-чего-либо) поточно-безопасного может привести к серьезным проблемам с производительностью .

Edit: перечитывая это, я чувствую себя обязанным указать, что не все использование COW обязательно устарело. Есть моменты, которые все еще имеют смысл. Накладные расходы на потокобезопасное приращение в значительной степени фиксированы - поэтому вопрос только в том, насколько большим должен быть объект или как дорого его копировать, чтобы COW имел смысл. Есть также времена / места, когда у вас есть лотов копий (неизмененного) объекта, и экономия памяти может быть разумным компромиссом - экономия памяти оправдывает дополнительное процессорное время. Если вы можете сохранить подкачку небольших данных на / с диска, вы можете выйти вперед в спешке.

2 голосов
/ 28 февраля 2010

Как сказал Джерри Коффин, было продемонстрировано, что идиома COW привела к проблемам с производительностью ... но на самом деле есть еще одна проблема.

Невозможно (как показано в самой статье, на которую вы ссылаетесь) фактически написать общую реализацию COW. В реализации COW std::string Копирование выполняется всякий раз, когда вызывается операция, которая фактически изменит состояние строки. Однако как указатель должен это знать? У него нет знаний о классе, на который он указывает.

Например, давайте предположим, что я делаю это:

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

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

Oups! Я делаю копию объекта Foo, даже если он не будет изменен!

Проблема в том, что хотя этот класс COW помогает, на самом деле его нужно обернуть:

class Foo
{
public:

private:
  COWPointer<FooImpl> mImpl;
};

И тогда методы Foo, которые действительно изменяют объект, будут отвечать за копирование состояния FooImpl. Поэтому уверен, что класс помогает, но это не серебряная пуля.

И все эти проблемы ... не будучи уверенными в том, что на самом деле набирают производительность из-за проблем с синхронизацией в приложении MT ...

Не проще ли на самом деле избегать копирования, когда это возможно (используя ссылки / указатели), вместо того, чтобы настраивать свой класс на возможный выигрыш в некоторых ситуациях, которые будут наказывать пользователей, которые уже позаботились о проблемах производительности?

0 голосов
/ 08 октября 2011

Существует противоречие между «указателем» и «копированием при записи»: по определению разыменование указателя не меняет его, а изменение *p не меняет p.

Таким образом, указатель на const может быть разыменован, и результирующее lvalue может быть изменяемым.

Вы на самом деле говорите о контейнере из одного элемента, а не об указателе.

...