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