Эффективность копирования и замены для общих указателей

Это можно рассматривать как продолжение, например Почему общий указатель присваивает «своп»?.

Вопрос о Копии&Используется своп идиома например в ускорении.

Я понимаю, что выгода от копирования&Обмен заключается в повторном использовании существующего кода, что позволяет избежать дублирования и ошибок. Но есть 2 случая (фактически 1 может быть уменьшен до другого), где это не оптимально:

  1. Экземпляры умного указателя совпадают
  2. Содержащийся указатель такой же

За shared_ptr счетчики ссылок увеличивается атомно и для intrusive_ptr(только буст) они могут быть. Так что есть высокая цена за копию.

Этого можно избежать, если назначение было реализовано так:

smart_ptr& operator=(const smart_ptr& other){
if(this->ptr_ == other.ptr_) return *this;
smart_ptr(other).swap(*this); // I assume I can simply do this here, right?
return *this;
}
smart_ptr& operator=(smart_ptr&& other){
smart_ptr(std::move(other)).swap(*this);
return *this;
}

Разве это не было бы самой быстрой и безопасной реализацией или есть какая-то проблема, которую я не видел?

Если он самый быстрый, то почему его не используют boost или stdlib?

Чтобы уточнить пункт 2. рассмотрим следующий код:

smart_ptr a(new foo);
auto b = a;
...
// Eventually:
a = b;

Это не самостоятельное назначение как &a != &b, Копия&Своп делает связаны с ненужной модификацией счетчика ссылок.

1

Решение

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

Реальная стоимость копирования shared_ptr — это атомарный инкремент ссылки (который может включать использование мьютекса внизу).

Если вы действительно хотите проверить производительность обоих подходов, я бы порекомендовал получить тест Google библиотека и написать набор тестовых случаев (для самостоятельного назначения и всех других случаев) и для его измерения. Помните, что оптимизатор в наши дни может удивить ваш код, чтобы оптимизировать его. Без его измерения было бы трудно сказать, быстрее ли это, но я думаю, что как бы довольно дорогая версия без нее лучше 🙂

РЕДАКТИРОВАТЬ:

Если вы не хотите увеличивать счетчик ссылок (это дорогостоящая часть с копированием shared_ptr), вы всегда можете использовать конструктор перемещения:

smart_ptr a(new foo);
auto b = a;
...
// Eventually:
a = std::move(b);
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector