C代码优化性能.doc
文本预览下载声明
在性能优化方面永远注意80-20原则,即20%的程序消耗了80%的运行时间,因而我们要改进效率,最主要是考虑改进那20%的代码。不要优化程序中开销不大的那80%,这是劳而无功的。第一招:以空间换时间 计算机程序中最大的矛盾是空间和时间的矛盾,那么,从这个角度出发逆向思维来考虑程序的效率问题,我们就有了解决问题的第1招--以空间换时间。比如说字符串的赋值:方法A:通常的办法#define LEN 32char string1 [LEN];memset (string1,0,LEN);strcpy (string1,This is a example!!);方法B:const char string2[LEN] =This is a example!;char * cp;cp = string2 使用的时候可以直接用指针来操作。从上面的例子可以看出,A和B的效率是不能比的。在同样的存储空间下,B直接使用指针就可以操作了,而A需要调用两个字符函数才能完成。B的缺点在于灵活 性没有A好。在需要频繁更改一个字符串内容的时候,A具有更好的灵活性;如果采用方法B,则需要预存许多字符串,虽然占用了大量的内存,但是获得了程序执 行的高效率。如果系统的实时性要求很高,内存还有一些,那我推荐你使用该招数。第二招: 使用宏而不是函数。 这也是第一招的变招。函数和宏的区别就在于,宏占用了大量的空间,而函数占用了时间。大家要知道的是,函数调用是要使用系统的栈来保存数据的,如果编 译器里有栈检查选项,一般在函数的头会嵌入一些汇编语句对当前栈进行检查;同时,CPU也要在函数调用时保存和恢复当前的现场,进行压栈和弹栈操作,所 以,函数调用需要一些CPU时间。而宏不存在这个问题。宏仅仅作为预先写好的代码嵌入到当前程序,不会产生函数调用,所以仅仅是占用了空间,在频繁调用同 一个宏的时候,该现象尤其突出。举例如下:方法C:#define bwMCDR2_ADDRESS 4#define bsMCDR2_ADDRESS 17int BIT_MASK(int __bf){ return ((1U (bw ## __bf)) - 1) (bs ## __bf);}void SET_BITS(int __dst,int __bf, int __val){ __dst = ((__dst) ~(BIT_MASK(__bf))) |\ (((__val) (bs ## __bf)) (BIT_MASK(__bf))))}SET_BITS(MCDR2, MCDR2_ADDRESS,ReGISterNumber);方法D:#define bwMCDR2_ADDRESS 4#define bsMCDR2_ADDRESS 17#define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)#define BIT_MASK(__bf)(((1U (bw ## __bf)) - 1) (bs ## __bf))#define SET_BITS(__dst, __bf, __val)\((__dst) = ((__dst) ~(BIT_MASK(__bf)))| \(((__val) (bs ## __bf)) (BIT_MASK(__bf))))SET_BITS(MCDR2, MCDR2_ADDRESS,RegisterNumber);D方法是我看到的最好的置位操作函数,是ARM公司源码的一部分,在短短的三行内实现了很多功能,几乎涵盖了所有的位操作功能。C方法是其变体,其中滋味还需大家仔细体会。第三招:数学方法解决问题 现在我们演绎高效C语言编写的第二招--采用数学方法来解决问题。数学是计算机之母,没有数学的依据和基础,就没有计算机的发展,所以在编写程序的时候,采用一些数学方法会对程序的执行效率有数量级的提高。举例如下,求 1~100的和。方法E:int I , j;for (I = 1 I=100; I ++){ j += I;}方法Fint I;I = (100 * (1+100)) / 2这个例子是我印象最深的一个数学用例,是我的计算机启蒙老师考我的。当时我只有小学三年级,可惜我当时不知道用公式 N×(N+1)/ 2 来解决这个问题。方法E循环了100次才解决问题,也就是说最少用了100个赋值,100个判断,200个加法(I和j);而方法F仅仅用了1个加法,1 次乘法,1次除法。效果自然不言而喻。所以,现在我在编程序的时候,更多的是动脑筋找规律,最大限度地发挥数学的威力
显示全部