Je me suis toujours posé la question, d'autant plus que - il y a quelques années - j'ai également fait un tel test comparant les horaires d'un appel de méthode de membre standard avec un appel virtuel et j'étais vraiment en colère contre les résultats à ce moment-là, ayant des appels virtuels vides étant 8 fois plus lent que les non-virtuels.
Aujourd'hui, je devais décider d'utiliser ou non une fonction virtuelle pour allouer plus de mémoire dans ma classe de tampon, dans une application très critique pour les performances, alors j'ai cherché sur Google (et vous ai trouvé), et à la fin, j'ai refait le test.
// g++ -std=c++0x -o perf perf.cpp -lrt
#include <typeinfo> // typeid
#include <cstdio> // printf
#include <cstdlib> // atoll
#include <ctime> // clock_gettime
struct Virtual { virtual int call() { return 42; } };
struct Inline { inline int call() { return 42; } };
struct Normal { int call(); };
int Normal::call() { return 42; }
template<typename T>
void test(unsigned long long count) {
std::printf("Timing function calls of '%s' %llu times ...\n", typeid(T).name(), count);
timespec t0, t1;
clock_gettime(CLOCK_REALTIME, &t0);
T test;
while (count--) test.call();
clock_gettime(CLOCK_REALTIME, &t1);
t1.tv_sec -= t0.tv_sec;
t1.tv_nsec = t1.tv_nsec > t0.tv_nsec
? t1.tv_nsec - t0.tv_nsec
: 1000000000lu - t0.tv_nsec;
std::printf(" -- result: %d sec %ld nsec\n", t1.tv_sec, t1.tv_nsec);
}
template<typename T, typename Ua, typename... Un>
void test(unsigned long long count) {
test<T>(count);
test<Ua, Un...>(count);
}
int main(int argc, const char* argv[]) {
test<Inline, Normal, Virtual>(argc == 2 ? atoll(argv[1]) : 10000000000llu);
return 0;
}
Et j'ai été vraiment surpris que cela - en fait - n'ait vraiment plus d'importance. Bien qu'il soit logique d'avoir des inlines plus rapides que les non-virtuels, et qu'ils soient plus rapides que les virtuels, il s'agit souvent de la charge de l'ordinateur dans son ensemble, de savoir si votre cache contient les données nécessaires ou non, et même si vous pourrez peut-être optimiser au niveau du cache, je pense que cela devrait être fait par les développeurs du compilateur plus que par les développeurs d'applications.