哪一段代码效率更高?

时间:2012-06-07 13:36:00

标签: c performance

为了初始化100×100二维数组的所有元素,我们可以用两种方式完成:

方法1:

int a[100][100];
for(i=0; i<100; i++){
    for(j=0; j<100; j++){
        a[i][j] = 10;
    }
}

方法2:

int a[100][100];
for(j=0; j<100; j++){
    for(i=0; i<100; i++){
        a[i][j] = 10;
    }
}

现在我的问题是哪种方法更有效,为什么?

5 个答案:

答案 0 :(得分:8)

第一种方法,因为它将按顺序访问数组。

C以 row-major 顺序存储二维数组,这意味着a [i] [j]将与[i] [j + 1]相邻但不会与[a]相邻I + 1] [j]的。

另一种说同样的事情(概括为&gt; 2维)的方法是最右边的索引在内存中相邻。或者,递增索引意味着您必须跳过正在递增的索引右侧的所有维度。

答案 1 :(得分:2)

C11 standard,第6.5.2.1.3节表明存储了数组row-major。这意味着第一种方法是顺序访问内存,而第二种方法不是。 根据您的CPU缓存机制,RAM访问机制和阵列的尺寸,可以更快。但一般来说,我会说第一种方法更快。

答案 2 :(得分:1)

当你声明一个像int a[100][100]这样的数组时,它的内存布局是相同的,如果你声明int a[10000],这意味着你可以连续访问所有单元格,如果你只是迭代一个。

标准表明数组是按行存储的,这意味着内存中的前100个单元格将是a[0][0]a[0][99],然后是a[1][0]a[1][99]

在大多数CPU上,第一种方法会更快,因为CPU可以将(大部分)阵列加载到CPU缓存中,从而快速访问它。请注意,这可能因CPU而异。

答案 3 :(得分:1)

我怀疑两个循环的速度是相同的,实际上生成的代码是相同的。除非数组是易失性的,否则编译器可以自由切换循环,并且应该将它们切换到对目标机器更好的顺序。

答案 4 :(得分:0)

这取决于您使用的语言是row-major还是列专业。内存中的任何内容总是以一维方式布局,因此所有2D内容也以一维方式转换。 现在请注意,有两种方法可以做到这一点。

  1. i *(连续元素的数量)+ j 我在哪里排第一。和j是列号

  2. i *(列中元素的数量)+ j 其中i是列号,j是行号。

  3. 所以这里首先是一种将2D数组转换为1D方式的行主要方式,第二种方式是列主要方式。像C / C ++这样的语言是行主要的,所以它们遵循第一种方式。

    现在观察一下,根据行中元素的数量,你有点,(0,0)和(1,0),但是(0,0)和(0,1) )是相邻的。

    作为最终答案,您的问题取决于编程语言,无论它是行主要编程语言还是列专业。 在C / C ++中,因为它们是行主要的,所以第一个会更快。