提高代码的运行效率(2) 四

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

2、 在编写的代码的时候,我们强调需要对循环首先进行循环内部的计算,然后进行循环外面的计算。在此,我们可以进行下面一个测试:

void loop_analyse()
{
    int m = GetTickCount();
    int inner = 0;
    int outer = 0;
    for(outer = 0; outer < 1000; outer ++)
    {
        for (inner = 0; inner < 1000; inner ++)
        { 
            a[outer][inner] = inner;
        }

    }  
  
    printf("%d\n", GetTickCount() - m);

    m = 0;
    for(inner = 0; inner < 1000; inner ++)
    {
        for (outer = 0; outer < 1000; outer ++)
        {
            data[outer][inner] = inner;
        }

    }
    printf("%d\n", GetTickCount() - m);
}

    我们在VC6.0上面的测试结果是31、64。原因就是我们的数据在内存中间是按照先内存,然后再按照外层的顺序排列的。如果在计算的时候,我们首先使用了内部的数据,那么在cpu cache命中率上就会很高。相反,如果按照outer进行数据的遍历的话,那么就需要进行数据的不停跳转,在cpu cache上面也需要不停地进行刷新。在一旦cpu的cache命中率下降,就会重新将数据从内存加载到cpu的cache上面。等到循环得到一定的积累之后,就会在时间的运算上面发生很大的变化。两者之间的运行效率差异就会变得非常明显。

3、尽可能在循环的时候只运行本层的数据,我们可以做下面一个测试用例。

int data1[10000000] = {0,1};
int data2[10000000] = {0,1};

void loop_layer_test()
{
     int m = GetTickCount();
     int outer = 0;
     int inner = 0;
     for(outer = 0; outer < 10000000; outer ++)
     {
          data1[outer] = outer;
          data2[outer] = outer;
     }
     printf("%d\n", GetTickCount() - m);

     m = GetTickCount();;
     for(inner = 0; inner < 10000000; inner ++)
     {
         data1[inner] = inner;
     }

     for(outer = 0; outer < 10000000; outer ++)
     {
          data2[outer] = outer;
     }
     printf("%d\n", GetTickCount() - m);
}

    在我的VC6.0测试的时候,两者的运行差别时间还是挺大的,有兴趣的朋友可以在自己的机器上面好好试一下,看看是不是效果显著。其实道理和上面的准则是差不多的,只不过我们这一次涉及的单层循环的东西,不过在本质上还是差别不是很大。

原文地址:https://www.cnblogs.com/sier/p/5676475.html