C++代码优化经验总结.docx
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《C++代码优化经验总结.docx》由会员分享,可在线阅读,更多相关《C++代码优化经验总结.docx(26页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、C+代代码优化化经验总总结优化是一一个非常常大的主主题,本本文并不不是去深深入探讨讨性能分分析理论论,算法法的效率率,况且且我也没没有这个个能力。我只是是想把一一些可以以简单的的应用到到你的CC+代代码中的的优化技技术总结结在这里里,这样样,当你你遇到几几种不同同的编程程策略的的时候,就就可以对对每种策策略的性性能进行行一个大大概的估估计。这这也是本本文的目目的之所所在. 目录: 一. 优化化之前二. 声明明的放置置 三. 内联联函数 四. 优化化你的内内存使用用 五. 速度度优化 六. 最后后的求助助 一. 优优化之前前 在进进行优化化之前,我我们首先先应该做做的是发发现我们们代码的的瓶颈(
2、bbotttlenneckk)在哪哪里。 然而当你你做这件件事情的的时候切切忌从一一个deebugg-veersiion进进行推断断,因为为debbug-verrsioon中包包 含了许多多额外的的代码。一个ddebuug-vverssionn可执行行体要比比relleasse-vverssionn大出440%。那些额额 外的代码码都是用用来支持持调试的的,比如如说符号号的查找找。大多多数实现现都为ddebuug-vverssionn和reele ase-verrsioon提供供了不同同的opperaatorr neew以及及库函数数。而且且,一个个relleasse-vverssionn的执
3、行行 体可能已已经通过过多种途途径进行行了优化化,包括括不必要要的临时时对象的的消除,循循环展开开,把对对象 移入寄存存器,内内联等等等。 另外外,我们们要把调调试和优优化区分分开来,它它们是在在完成不不同的任任务。 debbug-verrsioon 是是 用来追捕捕buggs以及及检查程程序是否否有逻辑辑上的问问题。rreleeasee-veersiion则则是用来来做一些些性能上上 的调整以以及进行行优化。 下面就让让我们来来看看有有哪些代代码优化化技术吧吧! 二. 声声明的放放置 程序序中变量量和对象象的声明明放在什什么位置置将会对对性能产产生显著著影响。同样,对对posstfiix和
4、preffix运运算符的的选择也也会影响响性能。这一部部分我们们集中讨讨论四个个问题:初始化化v.ss 赋值值, 在程序确确实要使使用的地地方放置置声明,构构造函数数的初始始化列表表,prrefiix vv.s posstfiix运算算符 。 (1) 请使用用初始化化而不是是赋值 在CC语言中中只允许许在一个个函数体体的开头头进行变变量的声声明,然然而在CC+中中声明可可以出现现在 程序的任任何位置置。这样样做的目目的是希希望把对对象的声声明拖延延到确实实要使用用它的时时候再进进行。 这样做可可以有两两个好处处:1. 确保保了对象象在它被被使用前前不会被被程序的的其他部部分恶意意修改。如 果对
5、象在在开头就就被声明明然而却却在200行以后后才被使使用的话话,就不不能做这这样的保保证。22. 使使我们 有机会通通过用初初始化取取代赋值值来达到到性能的的提升,从从前声明明只能放放在开头头,然而而往往开开始 的时候我我们还没没有获得得我们想想要的值值,因此此初始化化所带来来的好处处就无法法被应用用。但是是现在 我们可以以在我们们获得了了想要的的值的时时候直接接进行初初始化,从从而省去去了一步步。注意意,或许许对 于基本类类型来说说,初始始化和赋赋值之间间可能不不会有什什么差异异,但是是对于用用户定义义的类型型来说 ,二者就就会带来来显著的的不同,因因为赋值值会多进进行一次次函数调调用-oo
6、perratoor =。因此此当我 们在赋值值和初始始化之间间进行选选择的话话,初始始化应该该是我们们的首选选。 (2) 把声明明放在合合适的位位置上 在一一些场合合,通过过移动声声明到合合适的位位置所带带来的性性能提升升应该引引起我们们足够的的重视 。例如: boool is_C_NNeedded(); vooid usee() CC c11; iif (is_C_NNeedded() = ffalsse) rretuurn; /c1 wass noot nneedded /usse cc1 hheree rretuurn; 上面这段段代码中中对象cc1即使使在有可可能不使使用它的的情况下下
7、也会被被创建,这这样我们们就会为为它付 出不必要要的花费费,有可可能你会会说一个个对象cc1能浪浪费多少少时间,但但是如果果是这种种情况呢呢:C c1110000;我我想就不不是说浪浪费就浪浪费了。但是我我们可以以通过移移动声明明c1的的位置来来改变这这种情 况: vooid usee() iif (is_C_NNeedded() = ffalsse) rretuurn; /c1 wass noot nneedded CC c11; /moovedd frrom thee bllockks begginnningg /usse cc1 hheree rretuurn; 怎么样,程程序的性性能是
8、不不是已经经得到很很大的改改善了呢呢?因此此请仔细细分析你你的代码码,把声声明 放在合适适的位置置上,它它所带来来的好处处是你难难以想象象的。 (3) 初始化化列表 我们们都知道道,初始始化列表表一般是是用来初初始化cconsst或者者reffereencee数据成成员。但但是由于于 他自身的的性质,我我们可以以通过使使用初始始化列表表来实现现性能的的提升。我们先先来看一一段程序序: cllasss Peersoon prrivaate: CC c_1; CC c_2; puubliic: PPersson(connst C& c1, coonstt C& c22 ): c_1(cc1), c
9、_2(cc2) ; 当然构造造函数我我们也可可以这样样写: Peersoon:Perrsonn(coonstt C& c11, cconsst CC& cc2) cc_1 = cc1; cc_2 = cc2; 那么究竟竟二者会会带来什什么样的的性能差差异呢,要要想搞清清楚这个个问题,我我们首先先要搞清清楚二者者 是如何执执行的,先先来看初初始化列列表:数数据成员员的声明明操作都都是在构构造函数数执行之之前就完完成 了,在构构造函数数中往往往完成的的只是赋赋值操作作,然而而初始化化列表直直接是在在数据成成员声明明的时 候就进行行了初始始化,因因此它只只执行了了一次ccopyy coonsttru
10、cctorr。再来来看在构构造函数数中赋值值的 情况:首首先,在在构造函函数执行行前会通通过deefauult connstrructtor创创建数据据成员,然然后在构构造函 数中通过过opeerattor =进行行赋值。因此它它就比初初始化列列表多进进行了一一次函数数调用。性能差差异 就出来了了。但是是请注意意,如果果你的数数据成员员都是基基本类型型的话,那那么为了了程序的的可读性性就 不要使用用初始化化列表了了,因为为编译器器对两者者产生的的汇编代代码是相相同的。 (4) posstfiix VVS ppreffix 运算符符 prrefiix运算算符+和比它的的posstfiix版本本效
11、率更更高,因因为当pposttfixx运算符符被使用用的时 候,会需需要一个个临时对对象来保保存改变变以前的的值。对对于基本本类型,编编译器会会消除这这一份额额外 的拷贝,但但是对于于用户定定义类型型,这似似乎是不不可能的的。因此此请你尽尽可能使使用prrefiix运算算符 。 三. 内内联函数数 内联联函数既既能够去去除函数数调用所所带来的的效率负负担又能能够保留留一般函函数的优优点。然然而, 内联函数数并不是是万能药药,在一一些情况况下,它它甚至能能够降低低程序的的性能。因此在在使用的的时候 应该慎重重。 1我们们先来看看看内联联函数给给我们带带来的好好处:从从一个用用户的角角度来看看,内
12、联联函数看看起来和和 普通函数数一样,它它可以有有参数和和返回值值,也可可以有自自己的作作用域,然然而它却却不会引引入一般般 函数调用用所带来来的负担担。另外外,它可可以比宏宏更安全全更容易易调试。 当然然有一点点应该意意识到,iinliine speeciffierr仅仅是是对编译译器的建建议,编编译器有有权利忽忽 略这个建建议。那那么编译译器是如如何决定定函数内内联与否否呢?一一般情况况下关键键性因素素包括函函数体 的大小,是是否有局局部对象象被声明明,函数数的复杂杂性等等等。 2那么么如果一一个函数数被声明明为innlinne但是是却没有有被内联联将会发发生什么么呢?理理论上,当当编译
13、器拒绝内内联一个个函数的的时候,那那个函数数会像普普通函数数一样被被对待,但但是还会会出现一一些其他他 的问题。例如下下面这段段代码: / TTimee.h #iinclludee #iinclludee ussingg naamesspacce sstd; cllasss Tiime puubliic: iinliine voiid SShoww() ffor (innt ii = 0; i110; i+) ccouttttimee(0)eendll; ; 因为成员员函数TTimee:SShoww()包包括一个个局部变变量和一一个foor循环环,所以以编译器器一般拒拒绝innlinne ,并
14、且把把它当作作一个普普通的成成员函数数。但是是这个包包含类声声明的头头文件会会被单独独的#iinclludee 进各个独独立的编编译单元元中: / ff1.ccpp #iinclludee TTimee.hjj vooid f1() TTimee t11; tt1.SShoww(); / ff2.ccpp #iinclludee TTimee.h vooid f2() TTimee t22; tt2.SShoww(); 结果编译译器为这这个程序序生成了了两个相相同成员员函数的的拷贝: vooid f1(); vooid f2(); innt mmainn() ff1(); ff2(); rre
15、tuurn 0; 当程程序被链链接的时时候,llinkker将将会面对对两个相相同的TTimee:SShoww()拷拷贝,于于是函数数重定义的连接接错误发发生。但但是老一一些的CC+实实现对付付这种情情况的办办法是通通过把一一个unn-innlinned函函 数当作sstattic来来处理。因此每每一份函函数拷贝贝仅仅在在自己的的编译单单元中可可见,这这样链接接错误 就解决了了,但是是在程序序中却会会留下多多份函数数拷贝。在这种种情况下下,程序序的性能能不但没没有提 升,反而而增加了了编译和和链接时时间以及及最终可可执行体体的大小小。 但是是幸运的的是,新新的C+标准准中关于于un-inlli
16、need函数数的说法法已经改改变。一一个符合合标准CC+ +实现应应该只生生成一份份函数拷拷贝。然然而,要要想所有有的编译译器都支支持这一一点可能能还需要要很长时时 间。另外外关于内内联函数数还有两两个更令令人头疼疼的问题题。第一一个问题题是该如如何进行行维护。一个 函数开始始的时候候可能以以内联的的形式出出现,但但是随着着系统的的扩展,函函数体可可能要求求添加额额外 的功能,结结果内联联函数就就变得不不太可能能,因此此需要把把inllinee sppeciifieer去除除以及把把函数体体 放到一个个单独的的源文件件中。另另一个问问题是当当内联函函数被应应用在代代码库的的时候产产生。当当内联
17、 函数改变变的时候候,用户户必须重重新编译译他们的的代码以以反映这这种改变变。然而而对于一一个非内内联函 数,用户户仅仅需需要重新新链接就就可以了了。 这里里想要说说的是,内内联函数数并不是是一个增增强性能能的灵丹丹妙药。只有当当函数非非常短小小的 时候它才才能得到到我们想想要的效效果,但但是如果果函数并并不是很很短而且且在很多多地方都都被调用用的话 ,那么将将会使得得可执行行体的体体积增大大。最令令人烦恼恼的还是是当编译译器拒绝绝内联的的时候。在老 的实现中中,结果果很不尽尽人意,虽虽然在新新的实现现中有很很大的改改善,但但是仍然然还是不不那么完完善 的。一些些编译器器能够足足够的聪聪明来指
18、指出哪些些函数可可以内联联哪些不不能,但但是,大大多数编编译器 就不那么么聪明了了,因此此这就需需要我们们的经验验来判断断。如果果内联函函数不能能增强行行能,就就避免 使用它! 四. 优优化你的的内存使使用 通常常优化都都有几个个方面:更快的的运行速速度,有有效的系系统资源源使用,更更小的内内存使用用。 一般情况况下,代代码优化化都是试试图在以以上各个个方面进进行改善善。重新新放置声声明技术术被证明明是消 除多余对对象的建建立和销销毁,这这样既减减小了程程序的大大小又加加快了运运行速度度。然而而其他的的优化 技术都是是基于一一个方面面-更快的的速度或或者是更更小的内内存使用用。有时时,这些些目
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 代码 优化 经验总结
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内