Подтвердить что ты не робот

Эффективность смарт-указателя С++

Сколько стоит использование интеллектуальных указателей, в частности boost:: shared_ptr, больше по сравнению с голыми указателями с точки зрения времени и памяти? Использует ли голые указатели лучше для высокопроизводительных частей игровых/встроенных систем? Порекомендовал ли вы использовать голые указатели или интеллектуальные указатели для компонентов с высокой производительностью?

4b9b3361

Ответ 1

Разделение интеллектуальных указателей обычно тривиально, конечно, для повышения в режиме деблокирования. Все контрольные проверки во время компиляции. (Умные указатели могли теоретически делать умные вещи по потокам). Это все еще оставляет много других операций. Никола упоминал о строительстве, копировании и уничтожении. Однако это не полный набор. Другие важные операции: замена, назначение и сброс на NULL. В принципе, любая операция, требующая умения.

Обратите внимание, что некоторые из этих операций исключаются некоторыми интеллектуальными указателями. Например. boost::scoped_ptr невозможно скопировать, не говоря уже о назначении. Поскольку это уменьшает количество операций, реализация может быть оптимизирована для этих меньших методов.

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

Ответ 2

Boost предоставляет различные интеллектуальные указатели. Как правило, не должно быть проблемой как занятость памяти, которая изменяется в соответствии с типом интеллектуального указателя, так и производительность. Для сравнения производительности вы можете проверить этот http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smarttests.htm.

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

Следующий фрагмент демонстрирует отсутствие потери производительности при использовании shared_ptr<> вместо необработанного указателя:

#include <iostream>
#include <tr1/memory>

int main()
{
#ifdef USE_SHARED_PTR
    std::tr1::shared_ptr<volatile int> i(new int(1));
#else
    volatile int * i = new int(1);
#endif

    long long int h = 0;

    for(long long int j=0;j < 10000000000LL; j++)
    {
        h += *i;
    }

    std::cout << h << std::endl;
    return 0;
}

Ответ 3

Единственный способ справиться с проблемами производительности - это профиль вашего кода. Во всяком случае, наибольшую часть проблем с производительностью можно представить; только профилирование укажет вам, где ваши узкие места лежат.

Если выяснится, что использование интеллектуальных указателей создает узкое место, где нет указателей raw, используйте исходные указатели! До тех пор я не стал бы слишком беспокоиться об этом; большинство операций с интеллектуальными указателями достаточно быстрые. Скорее всего, вы слишком часто сравниваете строки (или что-то в этом роде), чтобы они имели значение.

Ответ 4

Учетные указатели с подсчетом ссылок (наиболее распространенный тип) стоят дороже при копировании, создании и удалении. Эта дополнительная стоимость может быть существенной, если вы много копируете, потому что большинство из них являются потокобезопасными.

Если вам просто нужен указатель "auto-deleting", есть много злокачественных auto_ptr, или новый и блестящий (но еще не поддерживаемый) unique_ptr из С++ 0x.

Ответ 5

Когда я последний раз тестировал, с VC6, компилятор не смог оптимизировать код с помощью умного указателя, а также с помощью необработанного указателя. С тех пор ситуация может измениться.

Ответ 6

Там часто пропускается промежуточный дом между управляемым вручную "t20" (т.е. исходными указателями) и std::vector<boost::shared_ptr<T> >, в форме boost::ptr_container.

Они объединяют производительность контейнера с необработанным указателем с удобством контейнера интеллектуальных указателей (т.е. предоставляют функциональные возможности, которым люди хотели бы контейнеры STL std::auto_ptr, если которые работали).