C ++ Smart Pointer производительность - PullRequest
18 голосов
/ 21 ноября 2008

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

Ответы [ 6 ]

21 голосов
/ 21 ноября 2008

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

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

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

7 голосов
/ 21 ноября 2008

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

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

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

2 голосов
/ 19 марта 2009

На полпути часто пропускаются между «1001» (то есть необработанными указателями) с «ручным» управлением и std::vector<boost::shared_ptr<T> > в форме классов boost::ptr_container.

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

2 голосов
/ 21 ноября 2008

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

2 голосов
/ 21 ноября 2008

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

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

...