More Exceptional C++中文版试读(优化与性能)

More Exceptional C++ 读书笔记 More Exceptional C++ 读书笔记 Item 1 Switching Streams (1): 多考虑易读性,避免编写过渡简洁但是不易懂,不易维护的代码;    记个相当简洁的流切换代码:  (argc > 2 ? ofstream(argv[2], ios::out|ios::binary) : cout ) 1 ? ifstream(argv[1],      ios 阅读详情
[Herb Sutter 的名作More Exceptional C++中文版即将出版。作为本书译者,我很高兴将本书推荐给大家。征得华中科技大学出版社同意,我将公开部分译稿,敬请大家批评指正。] 

 

 

优化与性能

 

对程序员来说,效率总是很重要。在C和C++的传统中,效率是重要支柱之一,“不要为没有使用的东西支付任何成本”这一指导原则——也称为零成本原则——总是语言设计和程序库设计的中心,而且,在很大程度上也确实得到了实现。

 

在本章以及书后的两个附录中,我们对一些重要的C++优化问题进行了深入的观察,并分析了它们对现实世界代码的影响。应该在何时优化你的代码?如何优化?inline到底做了些什么?为什么花哨的优化能够(而且确实会)让我们陷入麻烦?最后一点,并且对我来说最有趣的一点:如果你是在写多线程代码,上面一些问题的答案会如何发生变化?毕竟,我们关心的是现实世界中的效率问题;虽然C++标准对线程避而不谈,但在程序设计领域的第一线,每天都有越来越多的程序员在写多线程的C++代码。他们会关心这些问题的答案。

 

 

条款12:内联

难度:4

和大多数人的看法相反,关键字inline其实并不是什么魔法。事实上,只是在被恰当运用的时候,它才会成为有用的工具。问题是:什么时候该使用它呢?

 

1. inline有什么作用?

 

2. 将函数内联会提高效率吗?

 

3. 何时应当决定使用内联函数?如何决定?

 

解答

 

1. inline有什么作用?

 

将一个函数声明为inline意味着告诉编译器:编译器可以将这个函数代码的拷贝直接放在每一个使用这个函数的地方。编译器可以选择这么做,或不这么做;如果编译器确实这么做了,将会避免函数调用的发生。


2. 将函数内联会提高效率吗?

 

不一定。

 

首先,在回答这个问题之前,如果不先问问自己到底想优化“什么”,你就会落入一个著名的陷阱。第一个问题应该是:“你所说的效率指的是什么?”在上面的提问中,所谓的效率指的是程序体积吗?抑或是内存占用?执行时间?开发速度?编译时间?或是其它什么东西?

 

其次,和大多数人的看法相反:对于效率的各个方面,内联可能使之改善,也可能使之恶化:

 

a) 程序体积。许多程序员认为,内联一定会增加程序的体积,因为程序拥有的将不只是函数代码的一份拷贝,编译器会在使用了那个函数的每个地方生成一份拷贝。通常来说这是对的,但并非总是如此。如果和“编译器为了执行函数调用而不得不生成的代码”的体积相比,内联函数的体积比它还小,那么,内联会减小程序体积。

 

b) 内存占用。除了(上面所说的)基本程序体积外,内联通常对程序的内存使用没有影响,或极少有影响。

 

c) 执行时间。很多程序员认为,将函数内联一定会提高运行速度,因为它避免了函数调用的开销;而且,透过了函数调用这层“障碍”,编译器的优化程序就有了更多大显身手的机会。这可能是正确的,但不总是正确:如果函数不是被极其频繁地调用,整个程序的执行时间通常不会有明显的改善。实际上,事情有可能适得其反。如果内联增加了调用函数(calling function)的体积,它会降低调用者的“引用局部性(locality of reference)”(译注:参见[Meyers96]条款18);这意味着,如果调用者的内部指令循环(inner loop)不再和处理器高速缓存的大小相匹配,整个程序的执行速度实际上会降低。

不要忘记:客观地说,大多数程序的速度并非受限于CPU。最常见的瓶颈可能在于I/O上的限制,这包括很多方面,如网络带宽或延迟、对文件或数据库的访问,等等。

 

d) 开发速度和编译时间。为了得到最有效的利用,被内联的代码必须对调用者可见;这意味着,调用者必须依赖于被内联代码的内部细节。依赖另一个模块的内部实现细节必然增加模块的实际耦合性(但不会增加理论耦合性,因为调用者实际上没有使用被调用者的任何内部实现。)通常情况下,当普通函数被修改时,调用者无需重新编译,只需重新链接。当内联函数被修改时,调用者必须重新编译。还有,内联函数本身会在调试时期单独影响开发速度,因为,要想单步跟踪到内联函数的内部,或者在内联函数内部管理断点,对大多数调试器来说会更困难。

有一种情况下,一些人会认为内联是对开发速度的一种优化(这一点有一些争议)——为了避免让数据成员为公有成员,提供一个存取函数(accessor,见后)是好的做


法,但写这样一个存取函数的代价可能很高。这种情况下,一些人会认为,使用内联会带来好的编码风格和更好的模块独立性。

 

最后请记住,如果你想用什么方式提高效率,总是先借助你的算法和数据结构。它们会给你的程序带来数量级的整体改善,而内联之类的过程优化(process optimization)通常(注意,“通常”)收效甚微。

 

不妨说“现在不行”

3. 何时应当决定使用内联函数?如何决定?

 

和使用其它任何一种优化技术一样,答案是:在分析工具告诉你这样做之前,不要贸然行事。这条原则有几个合理的例外——在有些场合下你可以毫不迟疑地内联一个函数:例如空函数,而且会持续保持为空;或者,你非得这么做不可的时候——例如,在写一个非输出模板(non-exported template)的时候。

 

设计准则

使用优化的第一条原则:不要使用它。

使用优化的第二条原则:还是不要使用它。

 

结论:只要增加了耦合性,内联就总是会带来成本;绝对不要为某个东西事先支付成本,除非你知道它会带来好处——也就是说,回报大于支出。

 

“但我总能找到瓶颈在哪儿!”你会这样想。别着急,不是你一个人这样想。大多数程序员都或多或少地这样想过,但他们还是错了。完全错了。对于代码中真正的瓶颈所在,程序员是臭名昭著的猜测者。有时侯,我们撞大运似地蒙对了。但大多数时候,我们的猜测是错误的。

 

通常,只有实验数据(或称分析结果)可以帮助我们找出真正的热点所在。如果不借助某种分析工具,十有八九,一个程序员不可能识别出他(她)的代码中头号热点或瓶颈所在。干这行很多年了,我曾遇到过几个反对这一事实的程序员,他们(或他们的同事)坚持认为这一事实对他们不适用,声称自己一向能够“感觉到”自己代码中的热点所在。多年来,我从没有看到过这样的宣言变成一贯的事实。我们善于欺骗自己。

 

最后注意,使用这条准则的另一个实际原因是:对于哪一个内联函数不应该被内联,分析工具并不善于识别。


关于密集计算任务(例如数值计算程序库)

一些人要编写短小紧凑的程序库代码,例如高级科学和工程计算程序库,这些人有时可以凭直觉使用内联,并做得很不错。然而,即使是这些程序员,他们也倾向于明智地使用内联,认为优化宜迟不宜早。注意,写一个模块,然后通过“打开内联”和“关闭内联”的方式来比较性能,这通常不是一个好主意,因为“全开”和“全闭”是一种很粗糙的分析方法,它只能告诉你一般情况。它不会告诉你哪个函数受益,也不会告诉你每个函数受益多少。即使在这些情况下,你也应该使用分析工具并基于它的建议去优化。

 

关于存取函数

会有一些人争辩说:只有一行代码的存取函数(例如“X& Y::f() { return myX_; }”)是个合理的例外,它“可以”或“应该” 被自动内联。我知道这样做的道理,但要小心行事。不管怎么说,所有被内联的代码都会增加耦合性。所以,除非你事先确信内联会带来好处,否则,将使用内联的决定延迟到分析之后是没有坏处的。到了那时,如果分析工具真的指出内联会有好处,你至少知道,你正在做的是值得做的事;而且,你也将耦合和可能的编译开销延迟了——延迟到你确实知道内联真的有必要的时候。这样做不会让你吃亏的,真的!

 

设计准则

在性能分析证明确实必要之前,避免内联或详细优化。

 

More Exceptional C++中文版:高级C++编程进阶实战指南 异常处理从来不是一个孤立的话题。它与 RAII、模板、设计模式、编译器优化紧密交织在一起。真正厉害的程序员,不是靠“避开异常”来写出稳定代码,而是利用异常机制本身去构建更可靠的系统。就像汽车的安全气囊,你不希望它弹出来,但一旦需要,它必须起作用。这种高度集成的设计思路,正引领着现代 C++ 向更可靠、更高效的方向演进。🚀本文还有配套的精品资源,点击获取。 阅读详情

相关推荐

More Exceptional c++ 中文版

More Exceptional C++是Exceptional C++的续篇。根据多年程序开发的实践经验、Herb Sutter向C++程序员提供了久经考验的程序设计技术和行之有效的解决方案,这些技术和方案对设计从小型工程到企业级应用的现代软件系统大有裨益。

《More Exceptional C++:40个新的工程难题、编程疑问及解决方法》(中文版)

《More Exceptional C++:40个新的工程难题、编程疑问及解决方法》(中文版)china-pub预订中 推荐语: 本书针对一定的主题,为程序员提供了简明扼要的指导,从而将学习时间和疑惑减至最少。本书内容包括泛型程序设计与c++标准库、优化与性能、异常安全议题及技术、继承与多态、内存及资源管理、自由函数与宏等。 本书内容全面丰富,论述翔实清晰,作者权威且经验丰富,是c++程序员...

yangzhiyong77 297

Exceptional C++(中文版)和More Exceptional C++(中、英文版)

Exceptional C++(中文版)和More Exceptional C++(中、英文版)

More_Exceptional_C++(中文)pdf

下载地址:网盘下载 More Exceptional C++是Exceptional C++的续篇。根据多年程序开发的实践经验、Herb Sutter向C++程序员提供了久经考验的程序设计技术和行之有效的解决方案,这些技术和方案对设计从小型工程到企业级应用的现代软件系统大有裨益。 围绕着40个编程难题, More Exceptional C++引...

weixin_30571465的博客 1115

Exceptional.C++

Exceptional.C++中文

exceptional c++ 与 more exceptional c++ 英文版

英文版 C++经典书籍 英文版看了也还行,主要是能锻炼自己,豆瓣评分8.4 加油

xx读书笔记

在本书中,Herb Sutter采用了独具匠心的“提问/解答”的方式来指导你学习C++的语言特性;在本书的每个专题中,HerbSutter合理地设想出你的疑问和困惑,又有如神助地猜到了你的(可能是错误的)解答,然后给你以指点并呈现出最佳方案,最后,还提炼解决类似问题的一般性原则。 本书适合的读者对象是中高级程序员,尽管如此,只要具备基本的C++功底和一定的程序设计经验,你完全可以理解和消化本书的

backard的专栏 643

[计算机科学经典著作].Addison.Wesley.-.More.Exceptional.C++.pdf

[计算机科学经典著作].Addison.Wesley.-.More.Exceptional.C++.pdf

More Exceptional C++ 中文版试读(译序及目录)

 [Herb Sutter 的名作More Exceptional C++中文版即将出版。作为本书译者,我很高兴将本书推荐给大家。征得华中科技大学出版社同意,我将公开部分译稿,敬请大家批评指正。]  与大师面对面(译序)  小提琴家穆特录制过一张唱片,收录的是贝多芬最伟大的两部小提琴作品1。聆听那张唱片,你仿佛听见贝多芬在向你倾诉他对音乐艺术的理解和感悟、为你解答小提琴音乐创作

lostmouse的专栏 1803

more exceptional c++中文版

more exceptional c++中文版

matlab安装libsvm常见问题

matlab安装libsvm常见问题 libsvm的官网链接:LIBSVM -- A Library for Support Vector Machines.

cqujcy的博客 1535

more exceptional c++读书笔记

Part1 我是在读完Scott Meyers的《Effective c++》之后才读到这本书的。能够讨论特定的主题而不是将一门语言作为一个整体来看待是我理解c++的首选方式,所以Sutter和Meyers的书非常适合我。 与Meyers系列相比,exception c++系列的主要优势在于,您可以告诉Sutter是更好的程序员。你可以相信Meyers 所说的一切都是正确的,但最终你真正得到的只是一些关于如何做某些事情的额外指示。另一方面,Sutter在同样的主题上讲得更深入一些,让你觉得自己可以写出更

itaoest的博客 413

告别配置烦恼!保姆级教程:在Windows 10/11上为QT5.14.2配置MSVC2017编译器(附VS2022组件避坑指南)

本文提供了一份详细的保姆级教程,指导如何在Windows 10/11上为QT5.14.2配置MSVC2017编译器,包括VS2022组件避坑指南。从环境准备到关键配置,再到调试工具验证和Qt Creator中的编译器设置,一步步解决常见问题,帮助开发者快速搭建稳定可靠的开发环境。

weixin_30615767的博客 503

More Exceptional C++起步于Exceptional C++驻足之处

古希腊哲学家苏格拉底通过向学生提问进行教学——他用那些精心构思的问题来指导学生,启发他们从已知得出结论;让他们认识到自己正在学习的事物如何相互联系,这些事物与他们已有的知识又如何联系。这种教学法如此出名,以致于我们今天把它专称为“苏格拉底问答法”。如果让我们也从学生的角度来看问题,苏格拉底的教学法将引导我们,促使我们思考,帮助我们联系并应用现有的知识去获取新知。 本书如同它的前任Exceptional C++ [Sutter00]一样,借鉴了苏格拉底的教学法。它假设你目前正身处C++产品软件开发的某个领域

博文视点(北京)官方博客 1339

Python实战:超分辨率图像质量评估全攻略——PSNR、SSIM、LPIPS与NIQE的代码实现与优化

本文详细介绍了在Python中实现超分辨率图像质量评估的完整方案,涵盖PSNR、SSIM、LPIPS和NIQE四大核心指标。通过模块化代码设计、多进程并行处理和GPU加速优化,帮助开发者构建高效、可扩展的评估系统,并提供了实战避坑指南与结果解读方法。

weixin_29053073的博客 476

基于51单片机的通讯聊天系统

通过编写51单片机通讯聊天程序,掌握51单片机的各个模块的知识点和运用C语言编写51单片机的能力。用51单片机与口袋开发板设计实现一个单片机与电脑串口助手实现通讯功能的程序。程序的主要功能如下: 1 OLED初始化显示Welcome to Bluetooth communication! 字符串。 2 程序开始时处于接收信息模式, 电脑串口助手发送信息时,将从初始化字符第一个开始显示,电脑串口助手发送信息后,蜂鸣器响铃2秒左右。 3 每次同时按下左右键时,可以轮流切换接收/发送信息模式 4 在发送信息模式时

m0_47419053的博客 3640

C++ 为何如此强大?

在31年前(1979年),一名刚获得博士学位的研究员,为了开发一个软件项目发明了一门新编程语言,该研究员名为Bjarne Stroustrup,该门语言则命名为——C with classes,四年后改称为C++。

weixin_53644828的博客 289

开关电源辅助电源设计全流程拆解

地类型定义包含电路功率地(PGND)高压侧地,与主功率电路地相连整流桥负极、原边电感地、UC3842的功率地信号地(SGND)低压侧地,与控制/采样电路地相连副边整流管地、TL431地、MCU/运放地。

lyzh971103的博客 1475
上一篇: More Exceptional C++中文版试读(异常安全议题及技术)
下一篇: More Exceptional C++中文版试读(泛型程序设计与C++标准库)
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值