前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++对象的优化--减少不必要的函数调用

C++对象的优化--减少不必要的函数调用

作者头像
lexingsen
发布2022-02-25 08:44:17
4690
发布2022-02-25 08:44:17
举报
文章被收录于专栏:乐行僧的博客

测试环境:win10+vs2013 初始代码:

代码语言:javascript
复制
#include <iostream>
using namespace std;


class Test {
private:
	int ma;
public:
	Test(int data = 10) :ma(data) {
		cout << "Test(int)" << endl;
	}

	Test(const Test& t) :ma(t.ma) {
		cout << "Test(const Test&)" << endl;
	}

	~Test() {
		cout << "~Test()" << endl;
	}

	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator=" << endl;
		return *this;
	}

	int getData() {
		return ma;
	}
};


Test getObject(Test t) {
	int val = t.getData();
	Test res(val);
	return res;
}

int main() {
	Test t1(10);
	Test t2;

	t2 = getObject(t1);
	return 0;
}

执行结果: 上面短短的三行代码,背后居然11次的函数调用,效率太低了!!!

在这里插入图片描述
在这里插入图片描述

一、函数参数要求传入对象时,使用引用传递

代码语言:javascript
复制
#include <iostream>
using namespace std;


class Test {
private:
	int ma;
public:
	Test(int data = 10) :ma(data) {
		cout << "Test(int)" << endl;
	}
		
	Test(const Test& t) :ma(t.ma) {
		cout << "Test(const Test&)" << endl;
	}

	~Test() {
		cout << "~Test()" << endl;
	}

	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator=" << endl;
		return *this;
	}

	int getData() {
		return ma;
	}
};

// 相对上边的代码 仅仅是将形式参数 Test t改为Test &t
Test getObject(Test& t) {
	int val = t.getData();
	Test res(val);
	return res;
}

int main() {
	Test t1(10);
	Test t2;

	t2 = getObject(t1);
	return 0;
}

执行结果:

在这里插入图片描述
在这里插入图片描述

可以看到,经过函数参数的优化(值传递->引用传递),减少了一次临时对象构造和析构的函数开销。 相对于之前,只有9次的函数调用,减少了两次!!!

二、函数返回时,返回临时对象,不要先定义对象,然后再返回。直接提前计算好构造该函数返回对象所需要的参数,直接返回临时对象。

代码语言:javascript
复制
#include <iostream>
using namespace std;


class Test {
private:
	int ma;
public:
	Test(int data = 10) :ma(data) {
		cout << "Test(int)" << endl;
	}

	Test(const Test& t) :ma(t.ma) {
		cout << "Test(const Test&)" << endl;
	}

	~Test() {
		cout << "~Test()" << endl;
	}

	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator=" << endl;
		return *this;
	}

	int getData() {
		return ma;
	}
};


Test getObject(Test &t) {
	int val = t.getData();
	// Test res(val);
	// return res;
	return Test(val);
}

int main() {
	Test t1(10);
	Test t2;

	t2 = getObject(t1);
	return 0;
}

执行结果:

在这里插入图片描述
在这里插入图片描述

相对于上一步优化,又减少了两次函数调用的开销!!!

三、当需要接受一个函数的返回值时,并且该返回值是一个对象,不要以赋值的方式接受,以初始化的方式接受。

代码语言:javascript
复制
#include <iostream>
using namespace std;


class Test {
private:
	int ma;
public:
	Test(int data = 10) :ma(data) {
		cout << "Test(int)" << endl;
	}

	Test(const Test& t) :ma(t.ma) {
		cout << "Test(const Test&)" << endl;
	}

	~Test() {
		cout << "~Test()" << endl;
	}

	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator=" << endl;
		return *this;
	}

	int getData() {
		return ma;
	}
};


Test getObject(Test &t) {
	int val = t.getData();
	// Test res(val);
	// return res;
	return Test(val);
}

int main() {
	Test t1(10);
	Test t2 = getObject(t1);// 初始化的方式接受

	// t2 = getObject(t1); // 赋值的方式接受
	return 0;
}

执行结果:

在这里插入图片描述
在这里插入图片描述

相对于初始的代码,同样是获取一个对象的功能,优化到现在只有两次的构造和两次析构的调用,程序减少了相当大的一部分的函数调用开销,程序的效率也得到了很大的提升。一次调用getObejct()函数可以减少7次的函数调用开销,那么100万次的调用,就能减少700万次的开销。量变产生质变!!! 对象优化的三条规则 1.当函数的形式参数需要传递对象时,不要用值接受,用引用接受。减少一次临时对象的构造和析构。 2.当函数的返回值为对象时,不要再函数题先定义好零时对象,然后再返回值。直接提前计算好构造该返回对象需要的参数,直接返回一个临时对象。 3.当接受函数返回值为对象的函数的返回值时,以初始化的方式接受,不要以赋值的方式接受。 tips:当以临时对象拷贝构造一个新对象时,编译器不会产生这个临时对象,直接以构造临时对象的方式直接构造新对象,减少一次临时对象的构造和析构。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档