博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
消除临时对象
阅读量:5155 次
发布时间:2019-06-13

本文共 1427 字,大约阅读时间需要 4 分钟。

消除临时对象

在我们的代码中,有些临时对象正在使用而我们并未察觉;

性能优化时,消除临时对象,特别是大的临时对象,对提升性能效果明显;
这里列出常见的临时对象产生的地方:

按值返回

按值返回函数结果,结果就是一个临时对象

string add(string s1,string s2){    string s3;    s3 = s1+s2;    return s3;}

解决方案:

在大多数场景下,这个临时对象可以通过按引用返回来消除;

void add(string s1,string s2,string& retvalue ){    retvalue = s1+s2;}

幸运的是,编译器通常会对按值返回做优化,将其改写为按引用返回;

但编译器做的也是非常保守的工作,仅对匿名返回临时对象做这种按引用传递;
以上函数就不会做,而以下函数,编译器会自动优化为按引用传递:

string add(string s1,string s2){    return s1+s2;}

注:返回值优化(RVO: return value Optimition):由编译器来完成将值返回转换为引用返回;

按值传递参数

按值传递参数,会有临时对象的分配

string add(string s1,string s2){    string s3;    s3 = s1+s2;    return s3;}

解决方案:

改为按引用传递(如果不希望函数内部修改,加上const修饰符)

string add(const string& s1, const string& s2){    string s3;    s3 = s1+s2;    return s3;}

类型不匹配的隐式转换

赋值操作两边不是同一类型时,如果右边可以作为作为的构造函数的参数做隐式转换,那么就会有临时对象的产生;

比如:

string s1; s1 = "A";

首先会产生一个临时对象string:string("A");

然后赋值给s1: s1 = string("A");

解决方案:

尽量使用相同类型,不用编译器来自动做隐式转换:
比如:
初始化:

string s1("A");

赋值:

string s1;s1.assign("A");

连续的对象之间的+操作符

例:

string s3;s3 = s1+ s2;

s1+s2的中间结果需要存到一个临时对象中,然后再赋值给s3;

解决方案:

采用+=操作符,一个个的加上需要的对象:

s3 = s1; s3+= s2;

当然,第一种写法更为优雅,第二种则性能高效;

当此处不是优化关键 路径上的时候,我们还是采用第一种写法就好;

成员对象的初始化

class MyClass{    MyClass(){ m_a = "A";}    private:        string m_a;}

成员对象放在构造函数中初始化,那么必然产生一个中间的临时对象;

解决方案:

采用成员初始化列表:

class MyClass{    MyClass():m_a("A"){}    private:        string m_a;}

Posted by: 大CC | 06AUG,2015

博客: []
Github:

转载于:https://www.cnblogs.com/me115/p/4707169.html

你可能感兴趣的文章
自己定义控件-仿iphone之ToggleButton&VoiceSeekBar
查看>>
正则表达式
查看>>
Android点击效果
查看>>
JAVA问题集锦Ⅰ
查看>>
写在前面的话
查看>>
java匿名对象_面向对象
查看>>
【坑】——待填?!
查看>>
LeetCode: Single Number I & II
查看>>
构建最小JDK Docker镜像 或者直接使用镜像:frolvlad/alpine-oraclejre8:slim
查看>>
hah
查看>>
js detect the type of device
查看>>
查看daemon使用技巧
查看>>
jzxx1000~1010题分析
查看>>
Windows Phone 8 与 windows 8 开发技术概览
查看>>
vue 画二维码
查看>>
大数除法(C++)
查看>>
大数乘法(C++)
查看>>
bash常用实例
查看>>
加密配置文件插件
查看>>
文件下载与文件对比
查看>>