# C++中虚函数(virtual function)到底有多慢

2017-03-02 10:12:03来源:http://blog.csdn.net/hengyunabc/article/details/7461919作者:hengyunabc人点击

## 一、理论分析

`			sum += v.at(i);       //要调用at函数00CF1305  mov         eax,dword ptr [ebx]     //取到对象的虚函数表地址00CF1307  mov         edx,dword ptr [eax+4]   //取到实际VirtualVector类的at函数地址，因为at是第二个虚函数，所以要+4，如果是clear则+8，push_back则不加00CF130A  push        esi                     //参数压栈00CF130B  mov         ecx,ebx                00CF130D  call        edx                     //调用真正的VirtualVector类的at函数`

CPU流水线的一个演示：http://www.pictutorials.com/Instruction_Pipeline.html

`	VirtualVector v(100);	v.push_back(1);	v.at(0);`

Vector类包装了一个数组，提供push_back，at，clear函数。

VirtualVector类继承了IVector，同样实现了push_back，at，clear函数，但是都是虚函数。

`#include #include #include using namespace std;const int size = 100000000;class Vector{private:	int *array;	int pos;public:	Vector(int size):array(new int[size]),pos(0)	{	}	void push_back(int val)	{		array[pos++] = val;	}	int at(int i)	{		return array[i];	}	void clear()	{		pos = 0;	}};class IVector{public:	virtual void push_back(int val) = 0;	virtual int at(int i) = 0;	virtual void clear() = 0;	virtual ~IVector() {};};class VirtualVector : public IVector{public:	int *array;	int pos;public:	VirtualVector(int size):array(new int[size]),pos(0)	{	}	void push_back(int val)	{		array[pos++] = val;	}	int at(int i)	{		return array[i];	}	void clear()	{		pos = 0;	}	~VirtualVector()	{		if(array != NULL)			delete array;	}};void testVectorPush(Vector& v){	v.clear();	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	nTimeStart = clock();    //	for(int i = 0; i < size; ++i)	{		v.push_back(i);		//cout<	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;}void testVectorAt(Vector& v){	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	int sum = 0;	nTimeStart = clock();    //	for(int j = 0; j < 1; ++j)	{		for(int i = 0; i < size; ++i)		{			sum += v.at(i);		}	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;	cout<<"sum:"<}void testVirtualVectorPush(IVector& v){	v.clear();	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	nTimeStart = clock();    //	for(int i = 0; i < size; ++i)	{		v.push_back(i);		//cout<	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;}void testVirtualVectorAt(IVector& v){	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	int sum = 0;	nTimeStart = clock();    //	for(int j = 0; j < 1; ++j)	{		for(int i = 0; i < size; ++i)		{			sum += v.at(i);		}	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;	cout<<"sum:"<}int main(){	cout<	VirtualVector *V = new VirtualVector(size);	cout<<"testVectorPush:"<	testVectorPush(*v);	testVectorPush(*v);	testVectorPush(*v);	testVectorPush(*v);	cout<<"testVirtualVectorPush:"<	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	cout<<"testVectorAt:"<	testVectorAt(*v);	testVectorAt(*v);	testVectorAt(*v);	testVectorAt(*v);	cout<<"testVirtualVectorAt:"<	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	return 0;}`

`#include #include #include using namespace std;const int size = 100000000;class Vector{private:	int *array;	int pos;public:	Vector(int size):array(new int[size]),pos(0)	{	}	void push_back(int val)	{		array[pos++] = val;	}	int at(int i)	{		return array[i];	}	void clear()	{		pos = 0;	}};class IVector{public:	virtual void push_back(int val) = 0;	virtual int at(int i) = 0;	virtual void clear() = 0;	virtual ~IVector() {};};class VirtualVector1 : public IVector{public:	int *array;	int pos;public:	VirtualVector1(int size):array(new int[size]),pos(0)	{	}	void push_back(int val)	{		array[1] = val;	}	int at(int i)	{		return array[1];	}	void clear()	{		pos = 0;	}	~VirtualVector1()	{		if(array != NULL)			delete array;	}};class VirtualVector2 : public VirtualVector1{public:	VirtualVector2(int size):VirtualVector1(size)	{	}	void push_back(int val)	{		array[2] = val;	}	int at(int i)	{		return array[2];	}	void clear()	{		pos = 0;	}};class VirtualVector3 : public VirtualVector2{public:	VirtualVector3(int size):VirtualVector2(size)	{	}	void push_back(int val)	{		array[3] = val;	}	int at(int i)	{		return array[3];	}	void clear()	{		pos = 0;	}};class VirtualVector4 : public VirtualVector3{public:	VirtualVector4(int size):VirtualVector3(size)	{	}	void push_back(int val)	{		array[4] = val;	}	int at(int i)	{		return array[4];	}	void clear()	{		pos = 0;	}};class VirtualVector5 : public VirtualVector4{public:	VirtualVector5(int size):VirtualVector4(size)	{	}	void push_back(int val)	{		array[5] = val;	}	int at(int i)	{		return array[5];	}	void clear()	{		pos = 0;	}};class VirtualVector6 : public VirtualVector5{public:	VirtualVector6(int size):VirtualVector5(size)	{	}	void push_back(int val)	{		array[6] = val;	}	int at(int i)	{		return array[6];	}	void clear()	{		pos = 0;	}};class VirtualVector : public VirtualVector6{public:	VirtualVector(int size):VirtualVector6(size)	{	}	void push_back(int val)	{		array[pos++] = val;	}	int at(int i)	{		return array[i];	}	void clear()	{		pos = 0;	}};void testVectorPush(Vector& v){	v.clear();	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	nTimeStart = clock();    //	for(int i = 0; i < size; ++i)	{		v.push_back(i);		//cout<	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;}void testVectorAt(Vector& v){	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	int sum = 0;	nTimeStart = clock();    //	for(int j = 0; j < 1; ++j)	{		for(int i = 0; i < size; ++i)		{			sum += v.at(i);		}	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;	cout<<"sum:"<}void testVirtualVectorPush(IVector& v){	v.clear();	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	nTimeStart = clock();    //	for(int i = 0; i < size; ++i)	{		v.push_back(i);		//cout<	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;}void testVirtualVectorAt(IVector& v){	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	int sum = 0;	nTimeStart = clock();    //	for(int j = 0; j < 1; ++j)	{		for(int i = 0; i < size; ++i)		{			sum += v.at(i);		}	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;	cout<<"sum:"<}int main(){	cout<	{		auto v = VirtualVector1(size);		v.push_back(0);		cout<	}	{		auto v = VirtualVector2(size);		v.push_back(0);		cout<	}	{		auto v = VirtualVector3(size);		v.push_back(0);		cout<	}	{		auto v = VirtualVector4(size);		v.push_back(0);		cout<	}	{		auto v = VirtualVector5(size);		v.push_back(0);		cout<	}	{		auto v = VirtualVector6(size);		v.push_back(0);		cout<	}	auto *v = new Vector(size);	auto *V = new VirtualVector(size);	cout<<"testVectorPush:"<	testVectorPush(*v);	testVectorPush(*v);	testVectorPush(*v);	testVectorPush(*v);	cout<<"testVirtualVectorPush:"<	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	cout<<"testVectorAt:"<	testVectorAt(*v);	testVectorAt(*v);	testVectorAt(*v);	testVectorAt(*v);	cout<<"testVirtualVectorAt:"<	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	return 0;}`

## 测试结果：

1层继承的测试结果：

 push_back at Vector 0.263s 0.04s VirtualVector 0.331s 0.222s 倍数 1.25 5.55

6层继承的测试结果：

 push_back at Vector 0.262s 0.041s VirtualVector 0.334s 0.223s 倍数 1.27 5.43

`	int at(int i)	{		sssForTest = 0;		for(int j = 0; j < 100; ++j)			sssForTest += j;		return array[i];	}`

`#include #include #include using namespace std;const int size = 100000000;int sssForTest = 0;class Vector{private:	int *array;	int pos;public:	Vector(int size):array(new int[size]),pos(0)	{	}	void push_back(int val)	{		array[pos++] = val;	}	int at(int i)	{		sssForTest = 0;		for(int j = 0; j < 100; ++j)			sssForTest += j;		return array[i];	}	void clear()	{		pos = 0;	}};class IVector{public:	virtual void push_back(int val) = 0;	virtual int at(int i) = 0;	virtual void clear() = 0;	virtual ~IVector() {};};class VirtualVector : public IVector{public:	int *array;	int pos;public:	VirtualVector(int size):array(new int[size]),pos(0)	{	}	void push_back(int val)	{		array[pos++] = val;	}	int at(int i)	{		sssForTest = 0;		for(int j = 0; j < 100; ++j)			sssForTest += j;		return array[i];	}	void clear()	{		pos = 0;	}	~VirtualVector()	{		if(array != NULL)			delete array;	}};void testVectorPush(Vector& v){	v.clear();	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	nTimeStart = clock();    //	for(int i = 0; i < size; ++i)	{		v.push_back(i);		//cout<	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;}void testVectorAt(Vector& v){	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	int sum = 0;	nTimeStart = clock();    //	for(int j = 0; j < 1; ++j)	{		for(int i = 0; i < size; ++i)		{			sum += v.at(i);		}	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;	cout<<"sum:"<}void testVirtualVectorPush(IVector& v){	v.clear();	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	nTimeStart = clock();    //	for(int i = 0; i < size; ++i)	{		v.push_back(i);		//cout<	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;}void testVirtualVectorAt(IVector& v){	clock_t nTimeStart;      //计时开始	clock_t nTimeStop;       //计时结束	int sum = 0;	nTimeStart = clock();    //	for(int j = 0; j < 1; ++j)	{		for(int i = 0; i < size; ++i)		{			sum += v.at(i);		}	}	nTimeStop = clock();    //	cout <<"耗时："<<(double)(nTimeStop - nTimeStart)/CLOCKS_PER_SEC<<"秒"<< endl;	cout<<"sum:"<}int main(){	cout<	VirtualVector *V = new VirtualVector(size);	cout<<"testVectorPush:"<	testVectorPush(*v);	testVectorPush(*v);	testVectorPush(*v);	testVectorPush(*v);	cout<<"testVirtualVectorPush:"<	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	testVirtualVectorPush(*V);	cout<<"testVectorAt:"<	testVectorAt(*v);	testVectorAt(*v);	testVectorAt(*v);	testVectorAt(*v);	cout<<"testVirtualVectorAt:"<	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	testVirtualVectorAt(*V);	return 0;}`

at操作中增加求和后的统计结果：

 push_back at 增加求和代码 Vector 0.265s 6.893s VirtualVector 0.328s 7.125s 倍数 1.23 1.03

## 三、总结：

BTW：测试cpu是i5。

TODO：测试指针函数，boost::bind的效率