Почему вызов виртуальной функции быстрее, чем dynamic_cast?

Я написал простой пример, который оценивает среднее время вызова виртуальной функции, используя интерфейс базового класса и dynamic_cast и вызов не виртуальной функции. Вот он:

#include <iostream>
#include <numeric>
#include <list>
#include <time.h>

#define CALL_COUNTER (3000)

__forceinline int someFunction()
{
  return 5;
}

struct Base
{
  virtual int virtualCall() = 0;
  virtual ~Base(){};
};

struct Derived : public Base
{
  Derived(){};
  virtual ~Derived(){};
  virtual int virtualCall(){ return someFunction(); };
  int notVirtualCall(){ return someFunction(); };
};


struct Derived2 : public Base
{
  Derived2(){};
  virtual ~Derived2(){};
  virtual int virtualCall(){ return someFunction(); };
  int notVirtualCall(){ return someFunction(); };
};

typedef std::list<double> Timings;

Base* createObject(int i)
{
  if(i % 2 > 0)
    return new Derived(); 
  else 
    return new Derived2(); 
}

void callDynamiccast(Timings& stat)
{
  for(unsigned i = 0; i < CALL_COUNTER; ++i)
  {
    Base* ptr = createObject(i);

    clock_t startTime = clock();

    for(int j = 0; j < CALL_COUNTER; ++j)
    {
      Derived* x = (dynamic_cast<Derived*>(ptr));
      if(x) x->notVirtualCall();
    }

    clock_t endTime = clock();
    double callTime = (double)(endTime - startTime) / CLOCKS_PER_SEC;
    stat.push_back(callTime);

    delete ptr;
  }
}

void callVirtual(Timings& stat)
{
  for(unsigned i = 0; i < CALL_COUNTER; ++i)
  {
    Base* ptr = createObject(i);

    clock_t startTime = clock();

    for(int j = 0; j < CALL_COUNTER; ++j)
      ptr->virtualCall();


    clock_t endTime = clock();
    double callTime = (double)(endTime - startTime) / CLOCKS_PER_SEC;
    stat.push_back(callTime);

     delete ptr;
  }
}

int main()
{
  double averageTime = 0;
  Timings timings;


  timings.clear();
  callDynamiccast(timings);
  averageTime = (double) std::accumulate<Timings::iterator, double>(timings.begin(), timings.end(), 0);
  averageTime /= timings.size();
  std::cout << "time for callDynamiccast: " << averageTime << std::endl;

  timings.clear();
  callVirtual(timings);
  averageTime = (double) std::accumulate<Timings::iterator, double>(timings.begin(), timings.end(), 0);
  averageTime /= timings.size();
  std::cout << "time for callVirtual: " << averageTime << std::endl;

  return 0;
}

Похоже, callDynamiccast занимает почти в два раза больше времени.

время для callDynamiccast: 0,000240333

время для callVirtual: 0,0001401

Любые идеи, почему это происходит?

EDITED: создание объекта теперь производится в отдельной функции, поэтому комплер не знает его реального типа. Почти тот же результат.

EDITED2: создайте два разных типа производных объектов.

8
задан D_E 31 March 2012 в 20:53
поделиться