1レベルの単一継承における仮想関数のオーバーヘッドを決定するために(おそらく非常に非科学的な)小さなテストを設定しました。得られた結果は、派生クラスに多態的にアクセスする場合と直接アクセスする場合でまったく同じでした。少し驚いたのは、関数が仮想として宣言されたときに導入される計算時間の大きさでした(以下の結果を参照)。
メンバー関数をそのように宣言するとき、非常に多くのオーバーヘッドがありますか?また、派生クラスに直接アクセスする場合でも、なぜそれがまだ存在するのですか?
コードは次のとおりです。
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;
平均で約338ミリ秒になります。
継承を削除して仮想関数を削除すると、平均で約38ミリ秒になります。
それはほぼ10分の1です!したがって、基本的に、仮想として宣言された関数がある場合、それを多態的に使用しなくても、オーバーヘッドは常に同じように存在しますか?
ありがとう。