#c #pointers #boost #smart-pointers #tr1
#c #указатели #повышение #интеллектуальные указатели #tr1
Вопрос:
Я понимаю, что существует (иногда значительное) снижение производительности при создании, назначении, копировании и уничтожении std:: tr1::shared_ptr или boost::shared_ptr (из-за механизмов подсчета ссылок). Правильно ли, что после создания доступ к указателю, обернутому shared_ptr, не приводит к снижению производительности?
другими словами: учитывая
std::tr1::shared_ptr<myClass> SharedA(new myClass);
myClass *NakedA = new myClass;
делает
SharedA->someClassMember
имеют те же накладные расходы, что и
NakedA->someClassMember
?
Комментарии:
1. я не знаю, что происходит, когда вы его измеряете?
2. Каков выбор? Не использовать shared_ptr, хотя это необходимо?
3. @Doug T.- В простых тестовых примерах это, похоже, не имеет значения, однако в большом коде, над которым я работаю, мой профилировщик показывает некоторые накладные расходы при доступе к указателю (хотя кажется, что он должен быть встроенным и, следовательно, не имеет значения)
4. @Bo- технически управляемый указатель «не нужен». Это, как правило, хороший выбор дизайна, и в большинстве случаев его следует использовать. В моем случае (код научно-исследовательской группы) Я могу позволить себе накладные расходы на построение / назначение / etc, Но доступ к shared_ptr слишком сильно замедляет работу, и, насколько я понимаю, этого не должно быть.
5. Какой профилировщик вы используете? Профилировщик выборки не должен быть в состоянии определить разницу, если
operator->
метод был встроен. Инструментальный профилировщик будет регистрировать вызов метода, несмотря ни на что, и измерение будет искажено, потому что он не будет измерять использование простого старого->
оператора для простых старых указателей, потому что он вообще не будет использовать эти инструкции.
Ответ №1:
В оптимизированной сборке без поддержки отладки не должно быть никаких накладных расходов. Вы можете узнать, взглянув на реализацию, которую вы используете. Скорее всего, его operator->
перегрузка просто возвращает указатель на объект, на который указано, а его operator*
перегрузка просто разыменовывает этот указатель.
(Это то, что делает std::shared_ptr
реализация Visual C 2010: каждый из этих перегруженных операторов просто вызывает функцию «get», которая просто возвращает указатель; нет блокировки или других накладных расходов любого рода. Другие реализации могут отличаться.)
Неоптимизированная сборка может не встроить перегрузку оператора, и если ваша реализация имеет дополнительную поддержку отладки, которую вы включаете, она может выполнять дополнительные проверки (например, возможно, assert, если вы разыменовываете нулевой указатель).
Комментарии:
1. Спасибо, Джеймс — это то, что я подозревал, но не хотел продолжать преследовать свой хвост, если я не видел ясно.
Ответ №2:
Все функции-члены интеллектуального указателя, включая оператор разыменования, могут быть встроенными. Любой хороший компилятор должен оптимизировать абстракцию.