编辑:我从问题标题中删除了更快/更高效,因为它有误导性..我的意图不是优化而是理解数组。对不起,对不起!
int array[10][10], i, j;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
std::cin>>array[i][j];
}
对战
int array[10][10], i, j;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
std::cin>>array[j][i];
}
我很确定答案与如何在硬件级别实现数组有关; [] []语法只是程序员的抽象,以帮助可视化/建模。但是,我忘记了上面的代码从开始到结束依次访问内存块......
感谢所有答案......
只是为了确认我的理解,这是否意味着第一个代码相当于
int array[10][10], k;
for(k=0;k<100;k++)
{
std::cin>>*(array+k);
}
答案 0 :(得分:14)
除了等待获取用户输入将比阵列访问慢得多的事实之外,第一个更快。
如果您想了解有关该主题的更多背景信息,请查看this page on 2D array memory layout。
使用第二个,您正在检查A[0], A[10] ... A[1], A[11].
第一个是顺序A[0], A[1], A[2] ..
答案 1 :(得分:6)
第一个具有更好的空间局部性。因为第一个下标是子数组的索引,第二个下标是该子数组中的元素;因此,当您修复i
并改变j
时,您正在查看所有在子阵列中的元素,因此它们是紧密相连的;但是当你修复j
并改变i
时,你会看到10个(子阵列的长度)分开的元素,因此非常分散。
答案 2 :(得分:3)
我同意这是不成熟的优化,但是......
C ++以行主要顺序存储矩阵。这将导致第一种语法更快(在大多数硬件上),因为您在内存中按顺序访问数组,并保留数据访问中的位置。
有关阵列存储的详细信息,请see this article。
答案 3 :(得分:1)
在C ++中迭代数组的正确方法是第一种方法。像在第二个示例中所做的那样迭代一个“从外到内”的数组往往会更慢,因为在内部循环的每次迭代中,您将获得大不相同的内存位置。数组按顺序排列,第一种方法按内部行迭代。这为代码提供了有效使用CPU缓存的最佳机会,通过一次将一行加载到缓存中而不需要一直无效。
答案 4 :(得分:1)
对于小阵列来说,它不可能有任何区别!
但是对于较大的数组,第一个选项会更快,因为它将在序列中访问整个数组,因为它实际存储在内存中。此外,这将允许优化编译器访问整个技巧,以进一步加快速度。
对于阵列的每一次传递,第二个选项会弹回整个内存,这会降低缓存命中率,在最坏的情况下会涉及到大量的I / O分页虚拟内存的开启和关闭。
答案 5 :(得分:0)
您始终希望根据位置访问组中的内存位置,因此请先选择。 地方将在三个不同的层面发挥作用:
从处理器到处理器以及从操作系统到操作系统,情况各不相同,但只有很小的利润,除非你在谈论一些奇特的平台。