Virtual Functions and Performance C++

2019-02-21 22:19发布

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.

8条回答
SAY GOODBYE
2楼-- · 2019-02-21 23:11

With a small number of iterations there's a chance that your code is preempted with some other program running in parallel or swapping occurs or anything else operating system isolates your program from happens and you'll have the time it was suspended by the operating system included into your benchmark results. This is number one reason why you should run your code something like a dozen million times to measure anything more or less reliably.

查看更多
乱世女痞
3楼-- · 2019-02-21 23:17

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.

查看更多
登录 后发表回答