At school, we about virtual
functions in C++, and how they are resolved (or found, or matched, I don't know what the terminology is -- we're not studying in English) at execution time instead of compile time. The teacher also told us that compile-time resolution is much faster than execution-time (and it would make sense for it to be so). However, a quick experiment would suggest otherwise. I've built this small program:
#include <iostream>
#include <limits.h>
using namespace std;
class A {
public:
void f() {
// do nothing
}
};
class B: public A {
public:
void f() {
// do nothing
}
};
int main() {
unsigned int i;
A *a = new B;
for (i=0; i < UINT_MAX; i++) a->f();
return 0;
}
I compiled the program above and named it normal
. Then, I modified A
to look like this:
class A {
public:
virtual void f() {
// do nothing
}
};
Compiled and named it virtual
. Here are my results:
[felix@the-machine C]$ time ./normal
real 0m25.834s
user 0m25.742s
sys 0m0.000s
[felix@the-machine C]$ time ./virtual
real 0m24.630s
user 0m24.472s
sys 0m0.003s
[felix@the-machine C]$ time ./normal
real 0m25.860s
user 0m25.735s
sys 0m0.007s
[felix@the-machine C]$ time ./virtual
real 0m24.514s
user 0m24.475s
sys 0m0.000s
[felix@the-machine C]$ time ./normal
real 0m26.022s
user 0m25.795s
sys 0m0.013s
[felix@the-machine C]$ time ./virtual
real 0m24.503s
user 0m24.468s
sys 0m0.000s
There seems to be a steady ~1 second difference in favor of the virtual version. Why is this?
Relevant or not: dual-core pentium @ 2.80Ghz, no extra applications running between two tests. Archlinux with gcc 4.5.0. Compiling normally, like:
$ g++ test.cpp -o normal
Also, -Wall
doesn't spit out any warnings, either.
Edit: I have separated my program into A.cpp
, B.cpp
and main.cpp
. Also, I made the f()
(both A::f()
and B::f()
) function actually do something (x = 0 - x
where x
is a public
int
member of A
, initialized with 1 in A::A()
). Compiled this into six versions, here are my final results:
[felix@the-machine poo]$ time ./normal-unoptimized
real 0m31.172s
user 0m30.621s
sys 0m0.033s
[felix@the-machine poo]$ time ./normal-O2
real 0m2.417s
user 0m2.363s
sys 0m0.007s
[felix@the-machine poo]$ time ./normal-O3
real 0m2.495s
user 0m2.447s
sys 0m0.000s
[felix@the-machine poo]$ time ./virtual-unoptimized
real 0m32.386s
user 0m32.111s
sys 0m0.010s
[felix@the-machine poo]$ time ./virtual-O2
real 0m26.875s
user 0m26.668s
sys 0m0.003s
[felix@the-machine poo]$ time ./virtual-O3
real 0m26.905s
user 0m26.645s
sys 0m0.017s
Unoptimized is still 1 second faster when virtual, which I find a bit peculiar. But this was a nice experiment and would like to thank all of you for your answers!