한 수준의 단일 상속에서 가상 함수의 오버 헤드를 결정하기위한 (아마도 매우 비과학적인) 작은 테스트를 설정했고, 얻은 결과는 파생 함수에 액세스 할 때 정확히 동일했습니다 클래스를 다형 적으로 또는 직접 액세스 할 때. 약간의 놀라운 점은 함수가 가상으로 선언 될 때 도입 된 계산 시간의 크기의 순서 (아래 결과 참조)였습니다.가상 함수의 오버 헤드 테스트
멤버 함수를 선언 할 때 오버 헤드가 많이 발생하며 파생 클래스에 직접 액세스 할 때도 여전히 왜 존재합니까? 다음과 같이
코드는 다음과 같습니다
class base
{
public:
virtual ~base() {}
virtual uint func(uint i) = 0;
};
class derived : public base
{
public:
~derived() {}
uint func(uint i) { return i * 2; }
};
uint j = 0;
ulong k = 0;
double l = 0;
ushort numIters = 10;
base* mybase = new derived; // or derived* myderived = ...
for(ushort i = 0; i < numIters; i++)
{
clock_t start2, finish2;
start2 = clock();
for (uint j = 0; j < 100000000; ++j)
k += mybase->func(j);
finish2 = clock();
l += (double) (finish2 - start2);
std::cout << "Total duration: " << (double) (finish2 - start2) << " ms." << std::endl;
}
std::cout << "Making sure the loop is not optimized to nothing: " << k << std::endl;
std::cout << "Average duration: " << l/numIters << " ms." << std::endl;
결과 :
base* mybase = new derived;
가 ~ 338 밀리의 평균을 제공합니다.
derived* myderived = new derived;
은 평균 ~ 338ms를 제공합니다.
상속을 제거하고 가상 함수를 제거하면 평균 ~ 38 ms가됩니다.
거의 10 배 적습니다. 그래서 기본적으로 어떤 함수가 가상으로 선언된다면 비록 그것이 다형 적으로 사용되지 않더라도 오버 헤드는 항상 동일하게 존재할 것입니다.
감사합니다.
상속 + 가상 함수 비용을 함께 계산하는 것 같습니다. 가상 함수가없는 파생 클래스와 기본 클래스를 인스턴스화해야하는지 테스트해야합니다. –
왜 'new'를 사용합니까? 스택에있는 객체를 인스턴스화하는 것이 더 간단 할 것입니다 ... –
이 경우에는 아무런 차이가 없습니다. 포인터를 통해 액세스하는 경우 동일한 오버 헤드가 발생합니다. –