I played around with C++ trying to decrease build time by using pimpl and a base class.Having some arbitrary base class in the pointer I need to cast it to the real data type when I wanna use it.
For the pointer I tried *, shared_ptr and unique_ptr and took times with and without casting.
The code is very basic:
For my test I compiled it without optimization and with debugging enabled.
Optimization is awesome. Still when I work on a project most times I make debug builds because they are easier to debug. And when I can save time when debugging - then why not ;-)
Now the results (average of 8 tests):
BaseClass* static_cast<> ~5.6s
BaseClass* dynamic_cast<> ~6.3s
shared_ptr<BaseClass> static_pointer_cast<> ~9.0s
shared_ptr<BaseClass> dynamic_pointer_cast<> ~9.5s
shared_ptr<BaseClass> static_cast<ptr.get()> ~5.8s
shared_ptr<BaseClass> dynamic_cast<ptr.get()> ~6.5s
Using normal pointers is faster then smart pointers is kind of understandable because there is less to do and manage. Same goes for static versus dynamic cast.
But how can a static_cast from a normal pointer from a base class be faster then accessing the right class with a normal pointer directly?
What "normal" things can be seen?
→ A shared_ptr behaves as nearly as fast as a normal pointer.
→ A unique_ptr is slower then a shared_ptr.
→ A dynamic_(pointer_)cast is slower then a static_(pointer_)cast.
→ Casting shared_ptr is much slower then casting normal pointer.
So if you need to cast a lot - try to avoid smart pointers. Or cast the pointer that is inside the shared_ptr ( like this: static_cast<Derived_Class*>(baseClassSharedPointer.get()) ); But don't give that "free" pointer away!
When you know that the cast will work 100% of the time - prefer static cast.
If not 100% but most of the time then have a look at typeid.
Also: try to use smart pointers. Shared_ptr isn't that much slower then a normal pointer but you get some nice little extra: automatic destruction, and therefore maybe a bit less memory leaks ;-).