shared_ptr оверхед
От: Аноним  
Дата: 13.04.14 10:17
Оценка:
Не раз слышал, что рекомендуется использовать unique_ptr везде, где только можно вместо shared_ptr, из-за "тяжеловесности" последнего.
А в чем заключается оверхед?
Re: shared_ptr оверхед
От: Abyx Россия  
Дата: 13.04.14 10:21
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Не раз слышал, что рекомендуется использовать unique_ptr везде, где только можно вместо shared_ptr, из-за "тяжеловесности" последнего.

А>А в чем заключается оверхед?

в атомарности счетчика ссылок.
еще sizeof(shared_ptr<T>) == 2 * sizeof(void*)
In Zen We Trust
Re: shared_ptr оверхед
От: antropolog  
Дата: 13.04.14 11:23
Оценка: +3
А>Не раз слышал, что рекомендуется использовать unique_ptr везде, где только можно вместо shared_ptr, из-за "тяжеловесности" последнего.
у shared_ptr и unique_ptr прежде всего разная семантика, поэтому вопрос об "оверхедах" вообще не должен стоять, т.к. там где достаточно unique_ptr, не надо использовать shared_ptr, это сбивает с толку, и соответственно там где нужно использовть shared_ptr не надо использовать unique_ptr ( за этим уже конечно компилятор проследит )
Re: shared_ptr оверхед
От: Vamp Россия  
Дата: 13.04.14 14:23
Оценка: +2 -2
Здравствуйте, Аноним, Вы писали:

А>Не раз слышал, что рекомендуется использовать unique_ptr везде, где только можно вместо shared_ptr, из-за "тяжеловесности" последнего.

А>А в чем заключается ове
В 95% случаев использование shared ptr свидетельствует о недостаточной квалификации разработчика.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: shared_ptr оверхед
От: bnk СССР http://unmanagedvisio.com/
Дата: 13.04.14 14:36
Оценка:
Здравствуйте, Vamp, Вы писали:

А>>Не раз слышал, что рекомендуется использовать unique_ptr везде, где только можно вместо shared_ptr, из-за "тяжеловесности" последнего.


V>В 95% случаев использование shared ptr свидетельствует о недостаточной квалификации разработчика.


А что исползуют квалифицированные разработчики в тех случаях, где разработчики с недостаточной квалификацией используют shared_ptr?
Re[3]: shared_ptr оверхед
От: ononim  
Дата: 13.04.14 14:54
Оценка: +2 :))
V>>В 95% случаев использование shared ptr свидетельствует о недостаточной квалификации разработчика.
bnk>А что исползуют квалифицированные разработчики в тех случаях, где разработчики с недостаточной квалификацией используют shared_ptr?
только хардкор intrusive_ptr
Как много веселых ребят, и все делают велосипед...
Re: shared_ptr оверхед
От: IROV..  
Дата: 13.04.14 17:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Не раз слышал, что рекомендуется использовать unique_ptr везде, где только можно вместо shared_ptr, из-за "тяжеловесности" последнего.

А>А в чем заключается оверхед?
в том что для shared_ptr вызывается new.
используй intrusive_ptr
я не волшебник, я только учусь!
Re[3]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 13.04.14 19:13
Оценка:
Здравствуйте, bnk, Вы писали:

А>>>Не раз слышал, что рекомендуется использовать unique_ptr везде, где только можно вместо shared_ptr, из-за "тяжеловесности" последнего.

V>>В 95% случаев использование shared ptr свидетельствует о недостаточной квалификации разработчика.
bnk>А что исползуют квалифицированные разработчики в тех случаях, где разработчики с недостаточной квалификацией используют shared_ptr?

Типов проблем, для решения которых они по ошибке используют shared_ptr, много. Поэтому альтернатив тоже много:
1. Никаких owning ptr'ов, обычные scoped объекты
2. RVO, NRVO, move semantic
3. Boost.Variant-like
4. Гетерогенные контейнеры
5. Type-erasure, а-ля std::function
6. scoped_ptr
7. unique_ptr
8. ref counting без межпоточной синхронизации (например, на базе intrusive_ptr)

P.S. Помимо того, что shared_ptr'ом часто злоупотребляют, им ещё и пользуются неоптимально. Например не используют make_shared, делают лишние копии (с атомарным передёргивание внутри) когда достаточно move или const&.
Re[2]: shared_ptr оверхед
От: antropolog  
Дата: 13.04.14 21:06
Оценка: +1
Здравствуйте, Vamp, Вы писали:

V>В 95% случаев использование shared ptr свидетельствует о недостаточной квалификации разработчика.


я конечно понимаю, что дурак может и стеклянный половой орган разбить и руки порезать, но про "95%" это либо твоё личное окружение ( "мне вас жаль" ) либо откуда статистика?
Re[2]: shared_ptr оверхед
От: Abyx Россия  
Дата: 13.04.14 21:09
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Здравствуйте, Аноним, Вы писали:


А>>Не раз слышал, что рекомендуется использовать unique_ptr везде, где только можно вместо shared_ptr, из-за "тяжеловесности" последнего.

А>>А в чем заключается оверхед?
IRO>в том что для shared_ptr вызывается new.
что? какой еще new?
IRO>используй intrusive_ptr
In Zen We Trust
Re[4]: shared_ptr оверхед
От: antropolog  
Дата: 13.04.14 21:09
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>8. ref counting без межпоточной синхронизации (например, на базе intrusive_ptr)


что имелось здесь ввиду? во-первых у shared_ptr-а есть однопоточная версия без "оверхедов", а во-вторых в многопоточной где возможно используются атомарные операции. В чём здесь преимущество intrusive_ptr'а?
Re[3]: shared_ptr оверхед
От: Jack128  
Дата: 14.04.14 06:38
Оценка:
Здравствуйте, Abyx, Вы писали:

IRO>>в том что для shared_ptr вызывается new.

A>что? какой еще new?
Тот же, который в vector и string используется.
Re[5]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 14.04.14 08:03
Оценка:
Здравствуйте, antropolog, Вы писали:

EP>>8. ref counting без межпоточной синхронизации (например, на базе intrusive_ptr)

A>что имелось здесь ввиду? во-первых у shared_ptr-а есть однопоточная версия без "оверхедов"

Которая включается макросом? То есть которую нельзя использовать одновременно с многопоточной из-за ODR?

A>а во-вторых в многопоточной где возможно используются атомарные операции.


Что ты имеешь в виду? Ты про то, что атомарные дешевле mutex'а? Так они всё всё равно не бесплатные.

A>В чём здесь преимущество intrusive_ptr'а?


На базе intrusive_ptr можно сделать ref counting без межпоточной синхронизации (атомарные операции это тоже межпоточная синхронизация).
Re[4]: shared_ptr оверхед
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.04.14 08:12
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Тот же, который в vector и string используется.

т.е. shared_ptr сам внутрях создает объекты vector и string? оО
[irony]тогда да, такое использовать не стОит.[/irony]
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 14.04.14 08:34
Оценка:
Здравствуйте, antropolog, Вы писали:

V>>В 95% случаев использование shared ptr свидетельствует о недостаточной квалификации разработчика.

A>я конечно понимаю, что дурак может и стеклянный половой орган разбить и руки порезать, но про "95%" это либо твоё личное окружение ( "мне вас жаль" ) либо откуда статистика?

Эту тему даже Страуструп в своей презентации обыгрывал: Going Native 2012 keynote, 33:04.
Мол заменяют голый new (который, например, поставили из-за Java привычки), на shared_ptr, хотя достаточно unique_ptr, или даже вообще обычного scoped объекта.
Re[3]: shared_ptr оверхед
От: akochnev Россия  
Дата: 14.04.14 08:48
Оценка: +1
Здравствуйте, Abyx, Вы писали:

A>что? какой еще new?

shared_ptr помимо указателя на объект хранит еще и указатель на счетчик ссылок. Самый первый shared_ptr создает счетчик ссылок через вызов new.
Re[4]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 14.04.14 08:49
Оценка: 4 (3) +3
Здравствуйте, akochnev, Вы писали:

A>>что? какой еще new?

A>shared_ptr помимо указателя на объект хранит еще и указатель на счетчик ссылок. Самый первый shared_ptr создает счетчик ссылок через вызов new.

При использовании make_shared будет только одна аллокация.
Re[6]: shared_ptr оверхед
От: B0FEE664  
Дата: 14.04.14 08:54
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>На базе intrusive_ptr можно сделать ref counting без межпоточной синхронизации (атомарные операции это тоже межпоточная синхронизация).

А где почитать про переносимый ref counting без межпоточной синхронизации?
И каждый день — без права на ошибку...
Re[7]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 14.04.14 08:58
Оценка:
Здравствуйте, B0FEE664, Вы писали:

EP>>На базе intrusive_ptr можно сделать ref counting без межпоточной синхронизации (атомарные операции это тоже межпоточная синхронизация).

BFE>А где почитать про переносимый ref counting без межпоточной синхронизации?

Если известно, что твои ref-counting ptrs будут гулять только по одному потоку, то межпоточная синхронизация не нужна.
Re[5]: shared_ptr оверхед
От: Jack128  
Дата: 14.04.14 09:08
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, Jack128, Вы писали:


J>>Тот же, который в vector и string используется.

X>т.е. shared_ptr сам внутрях создает объекты vector и string? оО
Странная у тебя логика. А vector внутри себя использует new для создания vector'а ?
Ты ж вроде занимаешся сборкой какого то компилятора? Ну загляни в сорцы тамошнего stl, увидишь зачем там дин память нужна.
Re[6]: shared_ptr оверхед
От: real_sba http://cellwar.xyz/
Дата: 14.04.14 09:48
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Здравствуйте, niXman, Вы писали:


X>>Здравствуйте, Jack128, Вы писали:


J>>>Тот же, который в vector и string используется.

X>>т.е. shared_ptr сам внутрях создает объекты vector и string? оО
J>Странная у тебя логика. А vector внутри себя использует new для создания vector'а ?
J>Ты ж вроде занимаешся сборкой какого то компилятора? Ну загляни в сорцы тамошнего stl, увидишь зачем там дин память нужна.

Понятно что имеется ввиду несколько другой new. На сколько я понимаю/помню — весь смысл make_shared в том чтобы чтобы не было необходимости вызывать этот new.
Re[5]: shared_ptr оверхед
От: night beast СССР  
Дата: 14.04.14 09:59
Оценка: 7 (1) +2
Здравствуйте, Evgeny.Panasyuk, Вы писали:

A>>>что? какой еще new?

A>>shared_ptr помимо указателя на объект хранит еще и указатель на счетчик ссылок. Самый первый shared_ptr создает счетчик ссылок через вызов new.

EP>При использовании make_shared будет только одна аллокация.


ну, это не всегда хорошо. допустим объект большой и на него есть слабые ссылки...
Re[6]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 14.04.14 10:34
Оценка:
Здравствуйте, night beast, Вы писали:

A>>>>что? какой еще new?

A>>>shared_ptr помимо указателя на объект хранит еще и указатель на счетчик ссылок. Самый первый shared_ptr создает счетчик ссылок через вызов new.
EP>>При использовании make_shared будет только одна аллокация.
NB>ну, это не всегда хорошо. допустим объект большой и на него есть слабые ссылки...

Согласен, но тут либо лишняя аллокация, либо слабые ссылки держащие всю аллоцированную память. shared_ptr такой выбор предоставляет.
(можно ещё представить вариант специального взаимодействия с аллокатором, типа realloc в сторону уменьшения)
Re[7]: shared_ptr оверхед
От: Кодт Россия  
Дата: 14.04.14 10:57
Оценка:
Здравствуйте, real_sba, Вы писали:

_>Понятно что имеется ввиду несколько другой new. На сколько я понимаю/помню — весь смысл make_shared в том чтобы чтобы не было необходимости вызывать этот new.


Нет, смысл его в том, чтобы обеспечить транзакционность создания объекта и умного указателя на него.
void foo(shared_ptr<X> x, Y y);

void bar()
{
  foo(
    shared_ptr<X>( // 3) сюда не попали, new X утёк
      new X(123)   // 1) ok
    ),
    make_y()       // 2) throw
  );
}

void buz()
{
  foo(
    make_shared<X>(123), // 1) ok
                         // 3) удаляем временный объект
    make_y()             // 2) throw
  );
}


А какой там менеджер памяти будет задействован — new, malloc, что-то компиляторно-специфичное, — это уже десятое дело.
Бонусом можно протащить размещение объекта и счётчика в одном блоке памяти.
Перекуём баги на фичи!
Re[6]: shared_ptr оверхед
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.04.14 11:07
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Странная у тебя логика. А vector внутри себя использует new для создания vector'а ?

какой ответ, такой вопрос.

J>Ты ж вроде занимаешся сборкой какого то компилятора? Ну загляни в сорцы тамошнего stl, увидишь зачем там дин память нужна.

при использовании make_shared, производится только одна алокация и самого объекта, и счетчика ссылок.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[8]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 14.04.14 11:25
Оценка:
Здравствуйте, Кодт, Вы писали:

_>>Понятно что имеется ввиду несколько другой new. На сколько я понимаю/помню — весь смысл make_shared в том чтобы чтобы не было необходимости вызывать этот new.

К>Нет, смысл его в том, чтобы обеспечить транзакционность создания объекта и умного указателя на него.
К>[...]
К>А какой там менеджер памяти будет задействован — new, malloc, что-то компиляторно-специфичное, — это уже десятое дело.
К>Бонусом можно протащить размещение объекта и счётчика в одном блоке памяти.

И транзакционность, и бонус производительности являются полезными свойствами make_shared.
Но тут можно поспорить, что было раньше — курица или яйцо. Например make_shared существует уже давно, а вот про make_unique, который даёт только транзакционность, без бонуса производительности, вспомнили аж после релиза ISO C++11.
Re[9]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 14.04.14 11:33
Оценка: 32 (1)
EP>Здравствуйте, Кодт, Вы писали:

Вот, кстати, вырезка из ISO:

6 Remarks: Implementations should perform no more than one memory allocation. [ Note: This provides
efficiency equivalent to an intrusive smart pointer. —end note ]
7 [ Note: These functions will typically allocate more memory than sizeof(T) to allow for internal
bookkeeping structures such as the reference counts. —end note ]

Re[6]: shared_ptr оверхед
От: ononim  
Дата: 14.04.14 12:09
Оценка:
A>>>>что? какой еще new?
A>>>shared_ptr помимо указателя на объект хранит еще и указатель на счетчик ссылок. Самый первый shared_ptr создает счетчик ссылок через вызов new.
EP>>При использовании make_shared будет только одна аллокация.
NB>ну, это не всегда хорошо. допустим объект большой и на него есть слабые ссылки...
Ну и если слабые ссылки не нужны — все равно тратится место на weak_count, вроде бы. Если объектов 100500 и каждый — по 10-20 байт сам по себе — то весьма заметно будет.
Как много веселых ребят, и все делают велосипед...
Re[7]: shared_ptr оверхед
От: Jack128  
Дата: 14.04.14 12:57
Оценка:
Здравствуйте, niXman, Вы писали:

J>>Ты ж вроде занимаешся сборкой какого то компилятора? Ну загляни в сорцы тамошнего stl, увидишь зачем там дин память нужна.

X>при использовании make_shared, производится только одна алокация и самого объекта, и счетчика ссылок.

Вроде изначальный вопрос был "как оверхед дает shared_ptr" , а не "какой оверхед дает shared_ptr при его создании через make_shared" ?
Re[8]: shared_ptr оверхед
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.04.14 13:54
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Вроде изначальный вопрос был "как оверхед дает shared_ptr" , а не "какой оверхед дает shared_ptr при его создании через make_shared" ?

я хз как тебе, но мне очевидно, что создавать объекты shared_ptr без использования make_shared — как-то иррационально.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[9]: shared_ptr оверхед
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 14.04.14 15:30
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, Jack128, Вы писали:


J>>Вроде изначальный вопрос был "как оверхед дает shared_ptr" , а не "какой оверхед дает shared_ptr при его создании через make_shared" ?

X>я хз как тебе, но мне очевидно, что создавать объекты shared_ptr без использования make_shared — как-то иррационально.

Вовсе не очевидно. Если планируется держать weak_ptr на объекты, время жизни которых управляется с помощью shared_ptr, то возможно, более оптимальным будет отказаться от make_shared для экономии памяти.
Re[10]: shared_ptr оверхед
От: Evgeny.Panasyuk Россия  
Дата: 14.04.14 15:54
Оценка:
Здравствуйте, Lazin, Вы писали:

X>>я хз как тебе, но мне очевидно, что создавать объекты shared_ptr без использования make_shared — как-то иррационально.

L>Вовсе не очевидно. Если планируется держать weak_ptr на объекты, время жизни которых управляется с помощью shared_ptr, то возможно, более оптимальным будет отказаться от make_shared для экономии памяти.

Как заметил night beast, объекты ещё должны быть большими. Это означает, что:
1. размер object + ref_counting_data + alignment должен быть больше минимального кванта аллокации.
2. этот размер должен превышать некоторый практический порог, зависящий от конкретного приложения (например, кому-то намного важнее сделать меньше аллокаций, чем сэкономить несколько сотен байт).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.