C++代码优化方案(一)(二)

2014-11-24 11:31:54 · 作者: · 浏览: 1

float a, b, c, e, f;

。。。

e = a / c;

f = b / c;

新代码:

float a, b, c, e, f;

。。。

const float t(1.0f / c);

e = a * t;

f = b * t;

4、结构体成员的布局

  很多编译器有"使结构体字,双字或四字对齐"的选项。但是,还是需要改善结构体成员的对齐,有些编译器可能分配给结构体成员空间的顺序与他们声明的不同。但是,有些编译器并不提供这些功能,或者效果不好。所以,要在付出最少代价的情况下实现最好的结构体和结构体成员对齐,建议采取下列方法:
(1)按数据类型的长度排序

把结构体的成员按照它们的类型长度排序,声明成员时把长的类型放在短的前面。编译器要求把长型数据类型存放在偶数地址边界。在申明一个复杂的数据类型 (既有多字节数据又有单字节数据)时,应该首先存放多字节数据,然后再存放单字节数据,这样可以避免存储器的空洞。编译器自动地把结构的实例对齐在内存的偶数边界。

(2)把结构体填充成最长类型长度的整倍数

把结构体填充成最长类型长度的整倍数。照这样,如果结构体的第一个成员对齐了,所有整个结构体自然也就对齐了。下面的例子演示了如何对结构体成员进行重新排序:

旧代码: //普通顺序

struct

{

char a[5];

long k;

double x;

baz;

}

新代码: //新的顺序并手动填充了几个位元组

struct

{

double x;

long k;

char a[5];

char pad[7];

baz;

}

这个规则同样适用于类的成员的布局。

(3)按数据类型的长度排序本地变量

当编译器分配给本地变量空间时,它们的顺序和它们在源代码中声明的顺序一样,和上一条规则一样,应该把长的变量放在短的变量前面。如果第一个变量对齐了,其他变量就会连续的存放,而且不用填充字节自然就会对齐。有些编译器在分配变量时不会自动改变变量顺序,有些编译器不能产生4字节对齐的栈,所以4字节可能不对齐。下面这个例子演示了本地变量声明的重新排序:

   旧代码,普通顺序

short ga, gu, gi;

long foo, bar;

double x, y, z[3];

char a, b;

float baz;

新代码,改进的顺序

double z[3];

double x, y;

long foo, bar;

float baz;

short ga, gu, gi;

(4)把频繁使用的指针型参数拷贝到本地变量

避免在函数中频繁使用指针型参数指向的值。因为编译器不知道指针之间是否存在冲突,所以指针型参数往往不能被编译器优化。这样数据不能被存放在寄存器中,而且明显地占用了存储器带宽。注意,很多编译器有"假设不冲突"优化开关(在VC里必须手动添加编译器命令行/Oa或/Ow),这允许编译器假设两个不同的指针总是有不同的内容,这样就不用把指针型参数保存到本地变量。否则,请在函数一开始把指针指向的数据保存到本地变量。如果需要的话,在函数结束前拷贝回去。

旧代码:

// 假设 q != r

void isqrt(unsigned long a, unsigned long*q, unsigned long* r)

{

  *q = a;

  if (a >0)

  {

    while (*q> (*r = a / *q))

    {

      *q = (*q+ *r) >> 1;

    }

  }

  *r = a - *q* *q;

}

新代码:

// 假设 q != r

void isqrt(unsigned long a, unsigned long*q, unsigned long* r)

{

  unsignedlong qq, rr;

  qq = a;

  if (a >0)

  {

    while (qq> (rr = a / qq))

    {

      qq = (qq+ rr) >> 1;

    }

  }

  rr = a - qq* qq;

  *q = qq;

  *r = rr;

}


作者:chenlycly