How much do using smart pointers, particularly boost::shared_ptr cost more compared to bare pointers in terms of time and memory? Is using bare pointers better for performance intensive parts of gaming/embedded systems? Would you recommend using bare pointers or smart pointers for performance intensive components?
shared_ptr are noticeably slower than raw pointers. That's why they should only be used if you actually need shared ownership semantics. Otherwise, there are several other smart pointer types available. scoped_ptr and auto_ptr (C++03) or unique_ptr (C++0x) both have their uses.
Smart pointers are class objects that behave like raw pointers but manage objects that are new and when or whether to delete them— smart pointers automatically delete the managed object at the appropriate time.
Smart pointers should be preferred over raw pointers. If you feel you need to use pointers (first consider if you really do), you would normally want to use a smart pointer as this can alleviate many of the problems with raw pointers, mainly forgetting to delete the object and leaking memory.
As expected an std::shared_ptr is more expensive to use than a raw pointer and that's because it performs extra operations and allocates extra memory to handle the automatic memory management. It's important to notice that despite a 100% increase in time, we are still talking about 23ms per 1M pointers.
Dereferencing smart pointers is typically trivial, certainly for boost in release mode. All boost checks are at compile-time. (Smart pointers could in theory do smart stuff across threads). This still leaves a lot of other operations. Nicola mentioned construction, copying and destruction. This is not the complete set, though. Other important operations are swapping, assignment and resetting to NULL. Basically, any operation that requires smartness.
Note that some of these operations are excluded by some smart pointers. E.g. boost::scoped_ptr
cannot even be copied, let alone be assigned. As this leaves less operations, the implementation can be optimized for these fewer methods.
In fact, with TR1 coming up, it's quite likely that compilers can do better with smart pointers than raw pointers. E.g. it's possible that a compiler can prove that a smart non-copyable pointer is not aliased in some situations, merely because it's non-copyable. Think about it: aliasing occurs when two pointers are created pointing to the same object. If the first pointer cannot be copied, how would a second pointer end up pointing to the same object? (There are ways around that, too - operator* has to return an lvalue)
Boost provide different smart pointers. Generally both the memory occupation, which varies in accordance to the kind of smart pointer, and the performance should not be an issue. For a performance comparison you can check this http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smarttests.htm.
As you can see only construction, copy and destruction are taken into account for the performance comparison, which means that dereferencing a smart pointer has supposedly the same cost as that of a raw pointer.
The following snippet demonstrates that there's no performance loss by using a shared_ptr<>
in place of a raw pointer:
#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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With