How fast is dynamic_cast<>

三世轮回 提交于 2019-12-04 19:22:47


... approximately compared to a typical std::string::operator==()? I give some more details below, I'm not sure if they are of any relevance. Answer with complexity or approximation is good enough. Thanks!

Details: I will use it inside a for loop over a list to find some specific instances. I estimate my average level of inheritance to 3.5 classes. The one I'm looking for has a parent class, a grandparent and above that two "interfaces", i.e. to abstract classes with a couple of virtual void abc() = 0;.

There is no sub-class to the one I'll be looking for.


It depends hugely on your compiler, your particular class hierarchy, the hardware, all sorts of factors. You really need to measure it directly inside your particular application. You can use rdtsc or (on Windows) QueryPerformanceCounter to get a relatively high-precision timer for that purpose. Be sure to time loops or sleds of several thousand dynamic_cast<>s, because even QPC only has a ¼μs resolution.

In our app, a dynamic_cast<> costs about 1 microsecond, and a string comparison about 3ns/character.

Both dynamic_cast<> and stricmp() are at the top of our profiles, which means the performance cost of using them is significant. (Frankly in our line of work it's unacceptable to have those functions so high on the profile and I've had to go and rewrite a bunch of someone else's code that uses them.)


The best answer is to measure, my guess would be that dynamic_cast is faster than comparing any but the shortest strings (or perhaps even than short strings).

That being said, trying to determine the type of an object is usually a sign of bad design, according to Liskov's substitution principle you should just treat the object the same and have the virtual functions behave the correct way without examining the type from the outside.

Edit: After re-reading your question I'll stick to There is no sub-class to the one I'll be looking for. In that case you can use typeid directly, I believe it should be faster than either of your options (although looking for a specific type is still a code smell in my opinion)

#include <iostream>
#include <typeinfo>

struct top {
    virtual ~top() {} 

struct left : top { };
struct right : top { };

int main()
    left lft;
    top &tp = lft;   
    std::cout << std::boolalpha << (typeid(lft) == typeid(left)) << std::endl; 
    std::cout << std::boolalpha << (typeid(tp) == typeid(left)) << std::endl; 
    std::cout << std::boolalpha << (typeid(tp) == typeid(right)) << std::endl;