有关C++效率问题的文章, 说明的很不错! 值得一看。
原文来自于:http://www.host01.com/article/software/cc/20060917233227625.htm
=====================================================================
/*此文是译者出于自娱翻译的GotW(Guru of the Week)系列文章第二篇,原文的版权是属于Hub Sutter(著名的C++专家,"Exceptional C++"的作者)。此文的翻译没有征得原作者的同意,只供学习讨论。——译者
*/
#2 临时对象
难度:5/10
不必要的临时对象常常导致代码冗余和执行效率低下。
问题:
假设你正在看一段代码,代码中有如下一个函数。这个函数中至少有3处产生了不必要的临时对象。
看看你能够找出几处,该怎样修改?
string FindAddr( list<Employee> l, string name )
{
for( list<Employee>::iterator i = l.begin();
i != l.end();
i++ )
{
if( *i == name )
{
return (*i).addr;
}
}
return "";
}
答案:
不管你信不信,就在这寥寥几行代码里出现了三处明显的不必要的临时对象,两处不太明显的临时对象,还有一处值得注意的地方。
string FindAddr( list<Employee> l, string name )
^^^^^^^1^^^^^^^^ ^^^^^2^^^^^
1&2.参数应该是const引用类型.上述语句中的传值参数会导致list和string的拷贝操作,这可能是很耗时的。
[准则]尽量使用const&来代替值拷贝传递参数。
for( list<Employee>::iterator i = l.begin();
i != l.end();
i++ )
^3^
3.此处比上两处稍难看出。此处如果用前自增操作代替后自增的将更有效率,因为对象的后自增操作需要对象执行自增操作并返回一个自增前原值的临时对象(译者:重载过前自增和后自增操作符的读者应该都清楚二者的区别)。注意这种情况对于象int这样的C++原始类型也是适用的。
[准则]尽量使用前自增,避免使用后自增。
if( *i == name )
^4
4.虽然我们没有看到Employee类的定义,但是要使得上面的语句有效,这个类必须定义了到string类型转换操作符或者定义了以string类型为参数的构造函数。这两种情况都会产生一个临时对象,前者调用string的等值比较操作符(operator==),后者调用了Employee的等值比较操作符。(唯一不产生临时对象的情况就是string和Employee类中重载了以对方为参数类型的等值比较操作符。)
[准则]要小心隐藏在参数转换后面产生的临时对象。一个避免产生这种临时对象的解决办法就是用explicit修饰符对构造函数加以限制。
return "";
^5
5.此处产生了一个临时的空string对象。
更好的方法是声明一个局部的string对象来存放返回值,并且最后以一条返回该对象的值的语句作为统一的返回出口。这将使得编译器可以在某些情况下采用返回值优化手段省略掉这个局部对象。比如下面的情形:调用者通过如下代码调用这个函数:
string a = FindAddr( 1, "Harold" );
[准则]遵循单个出口原则。决不要在同一个函数中存在多个返回语句。
[注意:在作了更多的性能测试以后,我并不完全赞成上述的原则。《Exception C++》中已经对此作了不同阐述。]
string FindAddr( list<Employee> l, string name )
^^^*^^
*.此处是一个题外话,但很值得注意。看起来好像简单地将函数返回值类型从string类型改为引用类型sting&就又可以避免产生一个临时对象,但这是错误的!如果你幸运的话,你的程序会在函数调用者使用返回的引用时就马上崩溃,因为引用所指的局部对象已经不存在了。如果你不够幸运的话,你的程序看起来好像可以工作,但却不定期的崩溃,那将可能让你熬好几个晚上的长夜来调试找错。
[准则]千万千万不要将一个局部对象的引用作为返回值。
(注意:新闻组上有些人贴文正确的指出:可以通过声明一个静态对象,并在 没有查到对应雇员的地址时返回这个静态对象的引用,这样就可以把函数返回值改为引用类型而并不改变函数的语义。这同样也说明你在返回引用时必须了解所引用对象的生命周期以保证返回的引用有效。)
上述代码中还有一些可以优化的地方,比如可以避免调用end(),可以(或者说应该)使用一个const_iterator类型的迭代器。暂时不考虑这些,我们可以写出如下的较好的函数定义:
string FindAddr( const list<Employee>& l, const string& name )
{
string addr;
for( list<Employee>::const_iterator i = l.begin();
i != l.end();
++i )
{
if( (*i).name == name )
{
addr = (*i).addr;
break;
}
}
return addr;
}
分享到:
相关推荐
多重继承在C++中是一种强大的特性,允许一个类同时继承多个基类的属性和方法。然而,当这些基类中有相同名称的虚函数时,就会出现所谓的“菱形问题”(diamond problem),即子类如何正确地覆盖这些同名虚函数以实现...
名称:Clean Guru - cache & history cle ---------------------------------------- 版本:1.0.10 作者:Clean Guru 分类:实用工具 ---------------------------------------- 概述:Clean Guru是有用且轻巧的附加...
《Ken Henderson:The Guru's Guide to Transact-SQL》是一本深入探讨Transact-SQL语言的专业书籍,由Addison-Wesley出版社出版。该书在Book Pool评选的近十年计算机专业图书中脱颖而出,成为SQL领域的经典之作。...
通过以上对Guru of the Week系列案例的详细解析,我们可以看到Herb Sutter不仅为C++开发者提供了一系列高质量的技术问题和解答,而且还深入探讨了许多编程实践中的常见难题。无论是关于联合体的设计还是异常安全编码...
-a---- 2020/2/6 14:55 21598208 gopls.exe -a---- 2020/1/19 21:47 20195840 gopls.exe~ -a---- 2020/1/19 21:42 6575616 gorename.exe -a---- 2020/1/19 21:45 8217088 goreturns.exe -a---- 2020/1/19 21:42 ...
2 部分:AWS 10,000 英尺概览 第 3 部分:身份访问管理 第 4 部分:EC2 和获取设置 第 5 部分:S3 L50 - 云前端概述: L51 - 创建 CDN: 7.1. 设置:### 7.1.1. 7.1.2. 8.1. 8.2. 9.1. 9.2. 9.3. 9.3.1. 9.3.2. ...
书中涵盖了“Guru of the Week”(简称GotW)系列中的前30个条款,并对其进行了扩展。 #### 描述:通过实例进行坚实的软件工程 - **GotW**:GotW是由Herb Sutter创建的一个非常受欢迎的互联网C++特别节目,它以一...
PDF Guru v1.0.13 是一款全能的PDF处理工具,它提供了多种功能,旨在帮助用户高效地管理和编辑PDF文档。作为一个免费且开源的版本,它为用户提供了无需付费即可享受的专业级PDF解决方案。 首先,PDF Guru的核心功能...
Many of these problems are culled from the famous Guru of the Week feature of the Internet newsgroup comp.lang.c++.moderated, expanded and updated to conform to the official ISO/ANSI C++ Standard.
Many of these problems are culled from the famous Guru of the Week feature of the Internet newsgroup comp.lang.c++.moderated, expanded and updated to conform to the official ISO/ANSI C++ Standard....
颜色名称Guru :artist_palette: -Zeplin扩展 :alembic: 颜色名称大师为您的iOS,OSX,Web和Android项目提供颜色名称建议。 项目类型的默认颜色名称格式:iOS和OSX: camelCase Web: snake_case kebab-case Android...
资源分类:Python库 所属语言:Python 资源全名:mypy-boto3-devops-guru-1.18.2.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
资源分类:Python库 所属语言:Python 资源全名:mypy-boto3-devops-guru-1.18.63.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
Dobb's Journal, the former C++ Report, and other publications, and also as Guru of the Week [GotW] issues #63 to #86. The material in this book has been significantly revised, expanded, corrected, ...
- `LOB`类型:用于存储大对象,如`CLOB`(字符大对象),`BLOB`(二进制大对象),`BFILE`(二进制文件引用)等。 ### 行标识符和行计数器 - `ROWID`:Oracle中的每行都有一个唯一的ROWID,可以用来快速定位特定的...
Guru Able - Bootstrap 4 + Angular 4 Admin 演示站:https://wrapbootstrap.com/theme/guru-able-bootstrap-4-angular-4-admin-WB0RXR83D 功能完美
#Transforming into Your Teams Web Security Guru# ##O'Reilly Fluent 2015 会议演讲中的信息和链接:## ####重要起点#### 组织 关联 SANS OWASP CWE CVE 亚太经合组织 CWE/SANS 前 25 名最危险的软件错误 ...
其中许多问题来源于著名的“Guru of the Week”(GoW)这个互联网新闻组comp.lang.c++的特色功能。这些谜题和问题经过编辑和更新,以符合官方的ISO/ANSI C++标准。 每个问题都有一个难度评级,旨在通过解决过程中...
在Go语言的开发环境中,`gocode`、`godef`和`guru`是三个非常重要的工具,它们极大地提升了开发效率和代码理解能力。以下是关于这三个工具的详细解释: 1. **gocode**: `gocode`是Go语言的一个自动完成工具,它为...