2022年C++代码优化经验总结.docx
《2022年C++代码优化经验总结.docx》由会员分享,可在线阅读,更多相关《2022年C++代码优化经验总结.docx(32页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精品学习资源C+ 代码优化体会总结优化是一个特殊大的主题,本文并不是去深化探讨性能分析理论,算法的效率, 况且我也没有这个才能; 我只是想把一些可以简洁的应用到你的 C+代码中的优化技术总结在这里,这样,当你遇到几种不同的编程策略的时候, 就可以对每种策略的性能进行一个大致的估量;这也是本文的目的之所在 .目录:一.优化之前二.声明的放置三.内联函数四.优化你的内存使用五.速度优化六.最终的求助一.优化之前在进行优化之前,我们第一应当做的是发觉我们代码的瓶颈( bottleneck)在哪里;欢迎下载精品学习资源然而当你做这件事情的时候切忌从一个debug-version进行推断, 由于 deb
2、ug-version中包含了许多额外的代码;一个debug-version可执行体要比release-version大出 40%;那些额外的代码都是用来支持调试的,比如说符号的查找;大多数实现都为 debug-version和 release-version供应了不同的 operatornew以及库函数;而且,一个release-version的执行体可能已经通过多种途径进行了优化,包括不必要的临时对象的排除,循环开放,把对象移入寄存器,内联等等;另外,我们要把调试和优化区分开来,它们是在完成不同的任务; debug-version是用来追捕 bugs 以及检查程序是否有规律上的问题;rele
3、ase-version就是用来做一些性能上的调整以及进行优化;下面就让我们来看看有哪些代码优化技术吧!欢迎下载精品学习资源二.声明的放置程序中变量和对象的声明放在什么位置将会对性能产生显著影响;同样,对 postfix和prefix运算符的选择也会影响性能;这一部分我们集中争辩四个问题:初始化 v.s赋值,在程序的确要使用的地方放置声明,构造函数的初始化列表, prefixv.s postfix运算符;( 1) 请使用初始化而不是赋值在 C语言中只答应在一个函数体的开头进行变量的声明,然而在 C+中声明可以显现在程序的任何位置;这样做的目的是期望把对象的声明拖延到的确要使用它的时候再进行;这样
4、做可以有两个好处: 1.确保了对象在它被使用前不会被程序的其他部分恶意修改;如果对象在开头就被声明然而却在20 行以后才被使用的话, 就不能做这样的保证; 2.使我们欢迎下载精品学习资源有机会通过用初始化取代赋值来达到性能的提升,从前声明只能放在开头,然而往往开头的时候我们仍没有获得我们想要的值,因此初始化所带来的好处就无法被应用;但是现在我们可以在我们获得了想要的值的时候直接进行初始化,从而省去了一步;留意,或许对于基本类型来说,初始化和赋值之间可能不会有什么差异,但是对于用户定义的类型来说,二者就会带来显著的不同,由于赋值会多进行一次函数调用-operator =;因此当我们在赋值和初始化
5、之间进行选择的话,初始化应当是我们的首选;( 2) 把声明放在合适的位置上在一些场合,通过移动声明到合适的位置所带来的性能提升应当引起我们足够的重视;例如:bool is_C_Needed;欢迎下载精品学习资源void useC c1;if is_C_Needed = falsereturn; /c1 was not needed/use c1 herereturn;上面这段代码中对象 c1 即使在有可能不使用它的情形下也会被创建,这样我们就会为它付出不必要的花费, 有可能你会说一个对象 c1 能铺张多少时间, 但是假如是这种情形呢: Cc11000;我想就不是说铺张就铺张了; 但是我们可以通
6、过移动声明c1 的位置来转变这种情欢迎下载精品学习资源况:void useif is_C_Needed = falsereturn; /c1 was not neededC c1; /moved from the blocks beginning/use c1 herereturn;怎么样,程序的性能是不是已经得到很大的改善了呢?因此请仔细分析你的代码,把声明放在合适的位置上,它所带来的好处是你难以想象的;( 3) 初始化列表欢迎下载精品学习资源我们都知道,初始化列表一般是用来初始化const 或者reference数据成员;但是由于他自身的性质,我们可以通过使用初始化列表来实现性能的提升;我
7、们先来看一段程序:class Personprivate:C c_1;C c_2;public:Personconst C& c1, const C& c2 : c_1c1, c_2c2 ;当然构造函数我们也可以这样写:Person:Personconst C& c1, const C& c2欢迎下载精品学习资源c_1 = c1;c_2 = c2;那么究竟二者会带来什么样的性能差异呢,要想搞清楚这个问题, 我们第一要搞清楚二者是如何执行的,先来看初始化列表:数据成员的声明操作都是在构造函数执行之前就完成了,在构造函数中往往完成的只是赋值操作,然而初始化列表直接是在数据成员声明的时候就进行了初始
8、化,因此它只执行了一次copy constructor;再来看在构造函数中赋值的情形:第一,在构造函数执行前会通过default constructor创建数据成员,然后在构造函数中通过 operator=进行赋值;因此它就比初始化列表多进行了一次函数调用;性能差异就出来了;但是请留意,假如你的数据成员都是基本类型的话,那么为了程序的可读性就欢迎下载精品学习资源不要使用初始化列表了,由于编译器对两者产生的汇编代码是相同的;( 4) postfix VS prefix运算符prefix运算符+和比它的 postfix版本效率更高,由于当postfix运算符被使用的时候,会需要一个临时对象来储存转
9、变以前的值;对于基本类型,编译器会排除这一份额外的拷贝,但是对于用户定义类型,这似乎是不行能的;因此请你尽可能使用 prefix运算符;三.内联函数内联函数既能够去除函数调用所带来的效率负担又能够保留一般函数的优点;然而,内联函数并不是万能药,在一些情形下,它甚至能够降低程序的性能;因此在使用的时候应当谨慎;欢迎下载精品学习资源1. 我们先来看看内联函数给我们带来的好处:从一个用户的角度来看,内联函数看起来和一般函数一样,它可以有参数和返回值,也可以有自己的作用域, 然而它却不会引入一般函数调用所带来的负担;另外,它可以比宏更安全更简洁调试;当然有一点应当意识到, inlinespecifie
10、r仅仅是对编译器的建议,编译器有权益忽略这个建议;那么编译器是如何准备函数内联与否呢?一般情形下关键性因素包括函数体的大小,是否有局部对象被声明,函数的复杂性等等;2. 那么假如一个函数被声明为inline但是却没有被内联将会发生什么呢?理论上,当编译器拒绝内联一个函数的时候,那个函数会像一般函数一样被对待, 但是仍会显现一些其他的问题;例如下面这段代码:/ filename Time.h欢迎下载精品学习资源#include#includeusing namespace std;class Timepublic:inline void Show for int i = 0; i10; i+ c
11、outtime0endl;由于成员函数 Time:Show 包括一个局部变量和一个for循环,所以编译器一般拒绝 inline,并且把它当作一个一般的成员函数;但是这个包含类声明的头文件会被单独的 #include进各个独立的编译单元中:/ filename f1.cpp#include Time.hj欢迎下载精品学习资源void f1Time t1;t1.Show;/ filename f2.cpp#include Time.hvoid f2Time t2;t2.Show;结果编译器为这个程序生成了两个相同成员函数的拷贝:void f1;void f2;欢迎下载精品学习资源int mainf
12、1;f2;return 0;当程序被链接的时候,linker将会面对两个相同的Time:Show 拷贝,于是函数重定义的连接错误发生;但是老一些的C+实现应对这种情形的方法是通过把一个 un-inlined函数当作 static来处理;因此每一份函数拷贝仅仅在自己的编译单元中可见,这样链接错误就解决了,但是在程序中却会留下多份函数拷贝;在这种情形下, 程序的性能不但没有提升,反而增加了编译和链接时间以及最终可执行体的大小;欢迎下载精品学习资源但是幸运的是, 新的 C+标准中关于 un-inlined函数的说法已经转变;一个符合标准C+实现应当只生成一份函数拷贝; 然而,要想全部的编译器都支持这
13、一点可能仍需要很长时间;另外关于内联函数仍有两个更令人头疼的问题;第一个问题是该如何进行爱护;一个函数开头的时候可能以内联的形式显现,但是随着系统的扩展,函数体可能要求添加额外的功能,结果内联函数就变得不太可能,因此需要把inline specifier去除以及把函数体放到一个单独的源文件中;另一个问题是当内联函数被应用在代码库的时候产生;当内联函数转变的时候,用户必需重新编译他们的代码以反映这种转变;然而对于一个非内联函数,用户仅仅需要重新链接就可以了;欢迎下载精品学习资源这里想要说的是,内联函数并不是一个增强性能的灵丹妙药;只有当函数特殊短小的时候它才能得到我们想要的成效,但是假如函数并不
14、是很短而且在许多地方都被调用的话,那么将会使得可执行体的体积增大;最令人苦恼的仍是当编译器拒绝内联的时候;在老的实现中,结果很不尽人意,虽然在新的实现中有很大的改善,但是仍然仍是不那么完善的;一些编译器能够足够的聪慧来指出哪些函数可以内联哪些不能, 但是,大多数编译器就不那么聪慧了,因此这就需要我们的体会来判定;假如内联函数不能增强行能,就防止使用它!四.优化你的内存使用通常优化都有几个方面:更快的运行速度,有效的系统资源使用,更小的内存使用;欢迎下载精品学习资源一般情形下,代码优化都是试图在以上各个方面进行改善;重新放置声明技术被证明是消除余外对象的建立和销毁,这样既减小了程序的大小又加快了
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022 C+ 代码 优化 经验总结
限制150内