C++ Logo

std-proposals

Advanced search

[std-proposals] Caching the offset for dynamic_cast

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Wed, 10 Jul 2024 23:13:57 +0100
People complain about the performance of 'dynamic_cast'.

Starting out with the following class hierarchy:

    struct Base { virtual ~Base(void) = default; };
    struct Derived : Base {};
    struct MostDerived : Derived {};

And let's say we have defined just one variable:

    MostDerived var;

And let's say we have a pointer to its base:

    Base *p = &var;

Now let's say we have a standard library function something like:

    namespace std {
        template<class Dst, class Src>
        ptrdiff_f dynamic_cast_offset(type_info const &most_derived);
    }

We would call this function to cache the offset for a 'MostDerived' object:

    ptrdiff_t offset = dynamic_cast_offset<Derived,Base>(typeid(MostDerived));

And so then instead of doing:

    Derived *pd = dynamic_cast<Derived*>(p);

We would do:

    if ( typeid(*p) == typeid(MostDerived) ) pd = p + offset;

This could be an optimisation used for example in a function that 9
times out of 10 deals with the same most-derived type. Or even if
there are 3 commonly used types, we could do an if-else ladder:

    if ( typeid(*p) == typeid(MostDerived) ) pd = p + offset;
    else if ( typeid(*p) == typeid(MostDerived2) ) pd = p + offset2;
    else if ( typeid(*p) == typeid(MostDerived3) ) pd = p + offset3;
    else pd = dynamic_cast<Derived*>(p);

Received on 2024-07-10 22:14:10