0

Setting aside all the concerns about the necessity of using typeid and dynamic_cast and their questionable effects on code maintenance, is there any information about the performance of these two dynamic type introspection mechanisms? The Wikipedia article on RTTI claims that:

The use of typeid, in a non-polymorphic context, is often preferred over dynamic_cast<class_type> in situations where just the class information is needed, because typeid is always a constant-time procedure, whereas dynamic_cast may need to traverse the class derivation lattice of its argument at runtime.

However no citation is provided. As such I wanted to ask if this claim is true and if one of these two mechanisms should definitely be preferred performance-wise over the other. I wasn't able to find information about any bounds on time complexity of these operations.

janekb04
  • 4,304
  • 2
  • 20
  • 51
  • Maybe, have a look at cppreference.com: [typeid operator](https://en.cppreference.com/w/cpp/language/typeid): _When applied to an expression of polymorphic type, evaluation of a typeid expression may involve runtime overhead (a virtual table lookup), otherwise typeid expression is resolved at compile time._ – Scheff's Cat May 14 '21 at 11:35
  • Thanks for the quote. To me it suggests that the complexity is constant, as a vtable lookup would be just a couple pointer dereferences, but it is not explicitly stated if that is indeed the case. – janekb04 May 14 '21 at 11:44
  • It seems so: [Fiddling on Compiler Explorer](https://godbolt.org/z/chc4z93Ec) – Scheff's Cat May 14 '21 at 11:46
  • Though, maybe, the comparison is not quite fair. With `typeid`, you can check for a specific type but not whether the type is compatible (like you could with `dynamic_cast`): [Counter Example on Compiler Explorer](https://godbolt.org/z/chc4z93Ec) – Scheff's Cat May 14 '21 at 11:50
  • Though my assembly reading skills are not very good, if I understand correctly, in case of `typeid` the operation seems to be implemented as a pointer comparison between the pointers (stored in the vtable) to appropriate `std::type_info` objects. Clang even optimizes it out. Meanwhile, `dynamic_cast` calls an opaque function `__dynamic_cast` with the `std::type_info`s as arguments, so it's hard to say how its performance compares to that of `typeid` without knowing the implementation. Though, for sure, the function call itself is already an overhead that doesn't occur with `typeid`. – janekb04 May 14 '21 at 11:58
  • I don't read the asm fluidly either but came to the same conclusion. Considering that `dynamic_cast` is able to follow the inheritance tree, I assume it does a bit more than just comparing two vtable pointers. – Scheff's Cat May 14 '21 at 12:15
  • 1
    It seems like `type_info` doesn't really have to be that cheap. This question speaks of implementations that use `strcmp`: https://stackoverflow.com/questions/49773686/which-platforms-dont-use-string-comparison-in-type-info-op . This libstdc++ file seems to confirm: https://gcc.gnu.org/onlinedocs/gcc-7.5.0/libstdc++/api/a00035_source.html . – janekb04 May 14 '21 at 12:20

1 Answers1

1

The language standard doesn't impose any requirements about the complexity of either operation. As such, the statement that you quote isn't backed up by specification. It is presumably based on either how the functionality can be, or has been implemented in practice.

Bigger problem with the claim of preferability is that it is quite unclear how dynamic_cast even could be used in a non-polymorphic context.


If you're doing object oriented dynamic polymorphism, then what you should prefer is virtual functions.

eerorika
  • 232,697
  • 12
  • 197
  • 326