C++ Smart Pointer производительность

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

6 ответов

Решение

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

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

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

Повышение обеспечивают различные умные указатели. Как правило, как занятость памяти, которая варьируется в зависимости от типа интеллектуального указателя, так и производительность не должны быть проблемой. Для сравнения производительности вы можете проверить это 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;
}

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

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

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

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

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

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

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

Другие вопросы по тегам