Abhinav Gauniyal Abhinav Gauniyal - 2 months ago 16
C++ Question

calling base class method from polymorphic base pointer is slow

The title's pretty confusing.. Here's a minimal code to sum it up -

#include <iostream>
#include <chrono>
#include <memory>

using namespace std;
using namespace std::chrono;

enum class TYPE {base, child};

class Base {
int n;
protected: Base(int _n) : n(_n) {}
public: virtual TYPE getType(){ return TYPE::base; }
};

class Child: public Base {
int m;
public:
TYPE getType(){ return TYPE::child; }
Child(int _n, int _m) : Base(_n), m(_m) {}
};

int main() {
unique_ptr<Base> b = make_unique<Child>(6, 7);
TYPE tB = TYPE::base;
TYPE tC = TYPE::child;

{
auto t1 = high_resolution_clock::now();

std::cout << (tB == b->Base::getType()) << ", ";

auto t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>( t2 - t1 ).count();
cout << "Duration: " << duration << std::endl;

}

{
auto t1 = high_resolution_clock::now();

std::cout << (tC == b->getType()) << ", ";

auto t2 = high_resolution_clock::now();
auto duration = duration_cast<microseconds>( t2 - t1 ).count();
cout << "Duration: " << duration << std::endl;

}

return 0;
}


And the output is as follows -


1, Duration: 12 // first run was 62
1, Duration: 0



I understand how virtual functions might be little slower in comparison to normal(compileTime-resolved) functions, but how come the above function -
b->Base::getType()
is slower than virtual method -
b->getType()
? Is it doing two trips, like virtually resolving the function and then going back up to base class? Could anyone help me understand this?

IDEONE




Hmm, on slight modification of code to include loops, the results are clear -
IDEONE


1, Duration: 33
1, Duration: 1478051


Answer

Your timing numbers for the one function call are overwhelmed by the time used by the call to cout. The initial cout call is possibly allocating memory for a buffer, and would take longer.

The first call (b->Base::getType()) won't be virtual, and could even be inlined.