提升C++代码效率的几种方法一

提升C++代码效率的几种方法一

(1)条件分支造成的代码性能下降

实现条件操作的传统方法是通过使用控制的条件转移。当条件满足的时,程序沿着一条执行路径执行,而当条件不满足时,就走另一条路径。如以下代码:

long adsdiff(long x, long y)
{
    long result;
    if(x < y)
       result = y - x;
    else
       result = x - y;
    return result;
}

上述代码看起来很容易想到,但是却相当的低效。原因在于,处理器为了提高指令的执行速度,都会采取流水线的形式执行指令,即指令流水线。为了充满指令流水线,处理器会采用非常精密的分支预测逻辑来猜测每条跳转指令是否会执行。如果猜测正确,那么就会将之前预执行的指令的结果存储到寄存器或内存。如果猜测错误,那么处理器必须丢弃所有投机执行的结果,从正确的指令开始,重新开始取指令的过程。这期间浪费了大约15~30个时钟周期,导致程序性能严重下降。

对于以上程序,进行以下改进:

long adsdiff(long x, long y)
{
    long v1 = y - x, v2 = x - y;
    long result = v2;
    if(v1)
       result = v1;
    return result;
}

这个程序更加高效。但是这样的处理方法只能用在处理条件后面的表达式比较简单时的情况,比如加减表达式。如果表达式比较复杂,不建议用上述的方法,原因是如果相应的条件不满足,那么在前面所作的工作就白费了。

(2)循环造成的代码性能下降

1、减少过程(函数)调用

大家先看看以下代码:

//将大写字母转换成小写字母
void lower1(char *s)
{
    long i;
    for(i = 0; i < strlen(s); ++i)
        if(s[i] >= 'A' && s[i]) <= 'Z')
           s[i] -= ('A' - 'a');
}

上述代码每执行循环一次都会调用 strlen(s),且返回的值都是相同的,如果字符串 s 的长度很大,那么这段代码的运行时间将很长。那么,我们可以利用以下的方法来处理:

//将大写字母转换成小写字母
void lower1(char *s)
{
    long i;
    long len = strlen(s)
    for(i = 0; i < len; ++i)
        if(s[i] >= 'A' && s[i]) <= 'Z')
           s[i] -= ('A' - 'a');
}

将 strlen(s) 放到循环外部,执行代码时只调用一次,将大大地提升代码性能。

2、消除不必要地内存引用

看看以下代码:

//求数组元素的总和,放在 dest 所指的内存单元中
void combine(vector v, int *dest)
{
    int i;
    int length = v.size();
    int acc;
    for(auto c: v)
        *dest += *c;
}

每次执行循环,都会从内存中分别读取一次数据,内存的存取速度时较慢的。为了消除这些不必要的内存引用,将代码进行以下改进:

//求数组元素的总和,放在 dest 所指的内存单元中
void combine(vector v, int *dest)
{
    int i;
    int length = v.size();
    int acc;      //使用一个局部变量存储元素的总和
    for(auto c: v)
        acc += *c;
    *dest = acc;
}

上述代码将结果累积在一个局部变量(acc)中,局部变量通常都是放在寄存器中,寄存器的存取速度比内存快很多。最后再将结果读入到内存(*dest)中。

内容均来自《深入理解计算机系统》这本书,希望对大家编写代码有帮助。

你可能感兴趣的:(C++)