gpt4 book ai didi

c++ - 非虚拟成员的虚拟和继承成本?

转载 作者:搜寻专家 更新时间:2023-10-31 01:13:18 25 4
gpt4 key购买 nike

虚拟性可以有双重开销:

  • 内存(因为 vptr 和 vtable)
  • 运行速度

由于内存开销,当我需要非常高的内存优化时,我使用一些 CRTP 技术来获得一种静态虚拟性。

但我想知道非虚拟成员的运行速度的虚拟成本:

#include <iostream>

class Base
{
public:
Base() {;}
virtual ~Base() {;}

public:
virtual void f1() {std::cout<<"f1 : Base"<<std::endl; /* FUNCTION BODY */}
void f2() {std::cout<<"f2 : Base"<<std::endl; /* FUNCTION BODY */}
void f3() {f1();}
};

class Derived : public Base
{
public:
Derived() {;}
virtual ~Derived() {;}

public:
virtual void f1() {std::cout<<"f1 : Derived"<<std::endl; /* FUNCTION BODY */}
};

主要是:

int main()
{
Base b;
Derived d;
Base* ptr = new Derived();

std::cout<<std::endl;
b.f1(); // 1a
b.f2(); // 1b
b.f3(); // 1c
std::cout<<std::endl;
d.f1(); // 2a
d.f2(); // 2b
d.f3(); // 2c
std::cout<<std::endl;
ptr->f1(); // 3a
ptr->f2(); // 3b
ptr->f3(); // 3c
std::cout<<std::endl;

return 0;
}

对于每种情况:1a、1b ... 3c,与 Base 和 Derived 是两个完全独立的没有继承的类的情况相比,由于继承+虚拟性,我在哪里有运行时开销(执行时间增加)?

特别是 f2 函数是否有任何运行时开销?

注意:std::cout 只是一个例子。 /* FUNCTION BODY */ 可以是1k行代码...

最佳答案

为什么不只是计时呢?这是一个完全微不足道的练习..

首先,一些结果

100 million instances of b.f1() = 0.774852 secs.
100 million instances of b.f2() = 0.78162 secs.
100 million instances of b.f3() = 1.85278 secs.

100 million instances of d.f1() = 0.773115 secs.
100 million instances of d.f2() = 0.886528 secs.
100 million instances of d.f3() = 1.88562 secs.

100 million instances of ptr->f1() = 1.02043 secs.
100 million instances of ptr->f2() = 0.778072 secs.
100 million instances of ptr->f3() = 1.72503 secs.

假设是 win32,(QueryPerformanceXXXXX & LARGE_INTEGER) 您可以使用以下内容:

#include <windows.h>
#include <iostream>
using namespace std;

class Base
{
public:
Base() {;}
virtual ~Base() {;}

public:
virtual void f1() {};//std::cout<<"f1 : Base"<<std::endl; /* FUNCTION BODY */}
void f2() {}; //std::cout<<"f2 : Base"<<std::endl; /* FUNCTION BODY */}
void f3() {f1();}
};

class Derived : public Base
{
public:
Derived() {;}
virtual ~Derived() {;}

public:
virtual void f1() {};//std::cout<<"f1 : Derived"<<std::endl; /* FUNCTION BODY */}
};


LARGE_INTEGER clockFreq;

LARGE_INTEGER getTicks()
{
LARGE_INTEGER result;
QueryPerformanceCounter(&result);
return result;
}

double elapsedSecs(LARGE_INTEGER tStart, LARGE_INTEGER tEnd)
{
long ticksElapsed = tEnd.QuadPart - tStart.QuadPart;
double timePeriod = (double)ticksElapsed / (double)clockFreq.QuadPart;
return timePeriod;
}


int main()
{
LARGE_INTEGER tStart, tEnd;
Base b;
Derived d;
long i, max=100000000;

Base* ptr = new Derived();

// find how fast the clock ticks
QueryPerformanceFrequency(&clockFreq);


/*====================================================================================================
Test for access using b
b.f1()
b.f2()
b.f3()
====================================================================================================*/
std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
b.f1(); // 1a
}
tEnd = getTicks();
double elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of b.f1() = " << elapsed << " secs." << endl;


std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
b.f2(); // 1a
}
tEnd = getTicks();
elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of b.f2() = " << elapsed << " secs." << endl;

std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
b.f3(); // 1a
}
tEnd = getTicks();
elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of b.f3() = " << elapsed << " secs." << endl;


/*====================================================================================================
Test for access using d
d.f1()
d.f2()
d.f3()
====================================================================================================*/
std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
d.f1(); // 1a
}
tEnd = getTicks();
elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of d.f1() = " << elapsed << " secs." << endl;


std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
d.f2(); // 1a
}
tEnd = getTicks();
elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of d.f2() = " << elapsed << " secs." << endl;

std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
d.f3(); // 1a
}
tEnd = getTicks();
elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of d.f3() = " << elapsed << " secs." << endl;

/*====================================================================================================
Test for access using ptr
ptr->f1()
ptr->f2()
ptr->f3()
====================================================================================================*/
std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
ptr->f1(); // 1a
}
tEnd = getTicks();
elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of ptr->f1() = " << elapsed << " secs." << endl;


std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
ptr->f2(); // 1a
}
tEnd = getTicks();
elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of ptr->f2() = " << elapsed << " secs." << endl;

std::cout<<std::endl;
tStart = getTicks();
for (i=0; i<max; i++)
{
ptr->f3(); // 1a
}
tEnd = getTicks();
elapsed = elapsedSecs(tStart, tEnd);
cout << "100 million instances of ptr->f3() = " << elapsed << " secs." << endl;

return 0;
}

关于c++ - 非虚拟成员的虚拟和继承成本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12756672/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com