Is there a performance penalty when a virtual method is called from a class that's known to be the derived class at compile time? Below I explicitly call force_speak
with a derived class.
Code:
#include <iostream>
#include <array>
#include <memory>
class Base
{
public:
virtual void speak()
{
std::cout << "base" << std::endl;
}
};
class Derived1 : public Base
{
public:
void speak()
{
std::cout << "derived 1" << std::endl;
}
};
template<class B>
void force_speak(std::array<std::unique_ptr<B>, 3>& arr)
{
for (auto& b: arr)
{
b->speak();
}
}
int main()
{
std::array<std::unique_ptr<Derived1>, 3> arr =
{
std::unique_ptr<Derived1>(new Derived1),
std::unique_ptr<Derived1>(new Derived1),
std::unique_ptr<Derived1>(new Derived1)
};
force_speak(arr);
return 0;
}
Is there a performance penalty when a virtual method is called from a class that's known to be the derived class at compile time? See code below.
It depends. Most compilers will "de-virtualize" code like this:
Derived1 d;
d.speak();
The dynamic type of the object is known at the call site, so the compiler can avoid going through the vtable to make the call and can just call Derived1::speak()
directly.
In your example the compiler needs to be smarter because in force_speak
you only have Derived1*
pointers (stored inside the unique_ptr
objects) and in that context it's not clear whether the dynamic type of the pointed-to objects is Derived1
or some more-derived type. The compiler either needs to inline the call to force_speak
into main
(where the dynamic type is known) or use some additional knowledge about the type to allow devirtualization to happen. (As one example of additional knowledge, whole program optimization can determine that there are no other derived types declared anywhere in the program, so a Derived1*
must point to a Derived1
.)
Using the C++11 final
keyword can help compilers to devirtualize some cases, e.g. if Derived1
is marked final
then the compiler knows that a Derived1*
can only point to a Derived1
and not some other type derived from it that might override speak()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With