在时间和内存方面,使用智能指针,特别是boost::shared_ptr相比裸指针会增加多少开销?在游戏/嵌入式系统的性能密集部分中,使用裸指针是否更好?您是否建议在性能密集组件中使用裸指针还是智能指针?
在时间和内存方面,使用智能指针,特别是boost::shared_ptr相比裸指针会增加多少开销?在游戏/嵌入式系统的性能密集部分中,使用裸指针是否更好?您是否建议在性能密集组件中使用裸指针还是智能指针?
解引用智能指针通常很简单,特别是在boost的release模式下。所有boost检查都是在编译时进行的。(理论上智能指针可以在不同线程之间实现智能操作)。这仍然留下了许多其他操作。尼古拉提到了构造、复制和销毁。虽然这不是完整的集合,但还有其他重要的操作,如交换、赋值和重置为NULL。基本上,任何需要智能处理的操作。
请注意,一些智能指针排除了其中的某些操作。例如,boost::scoped_ptr
甚至不能被复制,更不能被分配。由于这减少了操作数,因此可以为这些较少的方法进行优化。
事实上,随着TR1的出现,编译器可能比裸指针更擅长处理智能指针。例如,编译器可以证明在某些情况下,一个智能的不可复制的指针并没有别名,只是因为它是不可复制的。想想看:当两个指针指向同一个对象时,才会发生别名。如果第一个指针无法被复制,第二个指针怎么会指向同一个对象呢?(也有办法绕过这个问题——operator*必须返回一个左值)
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;
}
解决性能问题的唯一方法是对你的代码进行分析。大部分性能问题都只存在于想象中;只有通过分析才能找出瓶颈所在。
如果使用智能指针会导致瓶颈而裸指针不会,那么就使用裸指针!在此之前,不必过多担心;智能指针上的大多数操作都相当快速。你可能会过于频繁地比较字符串(或类似的操作),以至于它们并不重要。
引用计数智能指针(最常见的类型)只有在复制、创建和删除它们时才会增加成本。如果您需要频繁进行复制,这种额外成本可能相当大,因为大多数智能指针都是线程安全的。
如果您只需要一个“自动删除”的指针,则可以使用备受诟病的auto_ptr,或者来自C++0x的新型炫酷(但支持程度不高)unique_ptr。
在我上次使用VC6进行测试时,编译器不能像使用裸指针那样优化智能指针的代码。自那时以来可能已经有所改变。
std::vector<T*>
(即原始指针)和std::vector<boost::shared_ptr<T> >
之间,即boost::ptr_container
类。这些类结合了原始指针容器的性能和智能指针容器的便利性(即它们提供了人们希望STL容器的std::auto_ptr
提供的功能,如果那样可行)。