Before you cringe at the duplicate title, the other question wasn't suited to what I ask here (IMO). So.
I am really wanting to use virtual functions in my application to make things a hundred times easier (isn't that what OOP is all about ;)). But I read somewhere they came at a performance cost, seeing nothing but the same old contrived hype of premature optimization, I decided to give it a quick whirl in a small benchmark test using:
CProfiler.cpp
#include "CProfiler.h"
CProfiler::CProfiler(void (*func)(void), unsigned int iterations) {
gettimeofday(&a, 0);
for (;iterations > 0; iterations --) {
func();
}
gettimeofday(&b, 0);
result = (b.tv_sec * (unsigned int)1e6 + b.tv_usec) - (a.tv_sec * (unsigned int)1e6 + a.tv_usec);
};
main.cpp
#include "CProfiler.h"
#include <iostream>
class CC {
protected:
int width, height, area;
};
class VCC {
protected:
int width, height, area;
public:
virtual void set_area () {}
};
class CS: public CC {
public:
void set_area () { area = width * height; }
};
class VCS: public VCC {
public:
void set_area () { area = width * height; }
};
void profileNonVirtual() {
CS *abc = new CS;
abc->set_area();
delete abc;
}
void profileVirtual() {
VCS *abc = new VCS;
abc->set_area();
delete abc;
}
int main() {
int iterations = 5000;
CProfiler prf2(&profileNonVirtual, iterations);
CProfiler prf(&profileVirtual, iterations);
std::cout << prf.result;
std::cout << "\n";
std::cout << prf2.result;
return 0;
}
At first I only did 100 and 10000 iterations, and the results were worrying: 4ms for non virtualised, and 250ms for the virtualised! I almost went "nooooooo" inside, but then I upped the iterations to around 500,000; to see the results become almost completely identical (maybe 5% slower without optimization flags enabled).
My question is, why was there such a significant change with a low amount of iterations compared to high amount? Was it purely because the virtual functions are hot in cache at that many iterations?
Disclaimer
I understand that my 'profiling' code is not perfect, but it, as it has, gives an estimate of things, which is all that matters at this level. Also I am asking these questions to learn, not to solely optimize my application.
I believe that your test case is too artificial to be of any great value.
First, inside your profiled function you dynamically allocate and deallocate an object as well as call a function, if you want to profile just the function call then you should do just that.
Second, you are not profiling a case where a virtual function call represents a viable alternative to a given problem. A virtual function call provides dynamic dispatch. You should try profiling a case such as where a virtual function call is used as an alternative to something using a switch-on-type anti-pattern.
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