What is the overhead of dynamic_cast<>

773 views Asked by At

So I have been programming in C++ for a while now, and I was told that using a dynamic cast to cast a pointer of an abstract class pointer to a different concrete class pointer was bad practice.

Shape* GeneralShape = new Triangle(...);
Triangle* triPtr = dynamic_cast<Triangle*>(GeneralShape);

Where Shape is an abstract class and Triangle inherits from it.

Using a dynamic cast just seems like a convenient way to access member functions when one of your inherited classes is just a little too different and needs more than the general functions that the abstract class contains. I was just wondering what's bad or what is the overhead in having run-time polymorphism?

1

There are 1 answers

0
Ben Voigt On

The "runtime overhead" of virtual dispatch is fairly low and not likely to matter except in tight loops:

  • Lookup of the correct function
  • Indirect call to function using its address
  • Pipeline stall if the CPU branch predictor mispredicted the call

dynamic_cast adds some additional overhead:

  • Walking the runtime representation of type inheritance to get the correct adjustment factor for the object pointer (or fail). This still is quite fast if the inheritance graph is not deep.

The larger cost is that of missed optimization opportunities at compile-time. In C++ in particular, using compile-time polymorphism (templates) very often results in a lot of inlining, elimination of loops, precomputation, etc. When run-time polymorphism is in play, these optimizations are generally not possible.

Interestingly, dynamic_cast is less of an obstacle to compile-time optimization because the compiler need only consider the two cases -- cast succeeds, and cast fails, which the programmer writes as two separate code paths both subject to optimization. In contrast, the "recommended" runtime polymorphism approach of using virtual calls is far more difficult to optimize because the set of possible types is open-ended.

Virtual calls are generally preferred over dynamic_cast (or tag-and-switch) for ease of maintenance (as @user4581301 comments), with performance considerations secondary.