编写高效的 C 和 C 代码优化

来源:互联网 发布:巨牌一搜网络一搜同志 编辑:程序博客网 时间:2024/06/05 00:24

英文原文在:http://www.codeproject.com/Articles/6154/Writing-Efficient-C-and-C-Code-Optimization


因为英文水平有限并且时间有限,本文只是记录一下该文章的观点,如有错误请指出,谢谢。


优化部分:

         1.用unsigned int 代替 int 

         备注:确保该参数不会为负数才能这样做。


2.少用除法,可将 (a / b) > c转变为 a > (c * b) 

备注:It will be better to use unsigned division by ensuring that one of the operands is unsigned, as this is faster than signed division.


3.

uint modulo_func1 (uint count){   return (++count % 60);}改为:uint modulo_func2 (uint count){   if (++count >= 60)  count = 0;  return (count);}
备注:Note that the new version only works if it is known that the range of count on input is 0-59.


4.

switch ( queue ) {case 0 :   letter = 'W';   break;case 1 :   letter = 'S';   break;case 2 :   letter = 'U';   break;}
<span style="color:#111111;"><span style="font-size: 14px;">if ( queue == 0 )  letter = 'W';else if ( queue == 1 )  letter = 'S';else  letter = 'U';</span></span>
以上两种都可以改为
static char *classes="WSU";  letter = classes[queue];

备注:这个要防止数组下标越界。。


5.

void func1( int *data ){    int i;    for(i=0; i<10; i++)    {          anyfunc( *data, i);    }}
改为
void func1( int *data ){    int i;    int localdata;    localdata = *data;    for(i=0; i<10; i++)    {          anyfunc ( localdata, i);    }}
理由:编译器不知道 anyfunc是否改变了*data的值,因此每次都要从内存中获取。

备注:因此这么使用要保证*data没有被改变


5.少用char和short类型,因为编译器会为这些变量进行特殊操作(原文有点绕,看不太懂,只知道是移位)

6.

typedef struct { int x, y, z; } Point3;typedef struct { Point3 *pos, *direction; } Object;void InitPos1(Object *p){   p->pos->x = 0;   p->pos->y = 0;   p->pos->z = 0;}

改成:

void InitPos2(Object *p){   Point3 *pos = p->pos;   pos->x = 0;   pos->y = 0;   pos->z = 0;}
备注:编译器不知道p->pos是否改变,因此每次使用的时候都要读内存。


7. 用switch 代替if else


8.

char * Condition_String1(int condition) {  switch(condition) {     case 0: return "EQ";     case 1: return "NE";     case 2: return "CS";     case 3: return "CC";     case 4: return "MI";     case 5: return "PL";     case 6: return "VS";     case 7: return "VC";     case 8: return "HI";     case 9: return "LS";     case 10: return "GE";     case 11: return "LT";     case 12: return "GT";     case 13: return "LE";     case 14: return "";     default: return 0;  }}
可以改为

char * Condition_String2(int condition) {   if ((unsigned) condition >= 15) return 0;      return      "EQ\0NE\0CS\0CC\0MI\0PL\0VS\0VC\0HI\0LS\0GE\0LT\0GT\0LE\0\0" +       3 * condition;}
备注:The first routine needs a total of 240 bytes, the second only 72 bytes.

个人看法:维护性稍稍差了一些。


9。让编译器明确知道范围,在编译的时候会进行优化,运行速度更快。例如n!。用递减的for循环比用递增的for循环快


10,函数传入参数最好在4个以内

       通过指向结构的指针,而不是通过结构本身来传递参数


11.多使用查询表


12如果库支持mallopt,用这个来替换malloc函数。

备注:

#include <malloc.h>
int mallopt(int param, int value)
 
功能:
    设置内存分配参数
       
详细说明:
    控制内存分配函数的行为,param表示参数,value表示值
    
 
参数:(param)
    M_TRIM_THRESHOLD
    堆的最小保持空间,只有超过这个设定值的堆内存,才有可能被sbrk回收,返还给系统
 
    M_TOP_PAD
    当在堆顶的空闲空间(通过sbrk释放得到的)到达设定的值时,则将这些内存还给系统。这样做的目的是在堆项保留一些空闲空间,防止频繁的申请内存的系统调用。
 
    M_MMAP_THRESHOLD
    超过这个设定值的内存分配,会采用mmap系统调用而不是brk
    
    M_MMAP_MAX

    使用mmap分配的最大chunk数量,0表示禁用mmapy
    The maximum number of chunks to allocate with mmap.Setting this to zero disables all use of mmap.


好了 就这么多了。。。。有兴趣的可以看英文原版。这个其实不全,可是对我来说就这么多可能用到。。。。

0 0
原创粉丝点击