当前位置: 首页 > 知识库问答 >
问题:

java - 循环1M大小二维数组matrix[x][y] ,下面哪种方式更快,并解释原理?

宓文斌
2023-07-03

循环1M大小二维数组matrixx ,下面哪种方式更快,并解释原理

1、for(int x=0;x<size;x++)
    for(int y=0;y<size;y++)
      matrix[x][y]=x+y;

2、for(int y=0;y<size;y++)
    for(int x=0;x<size;x++)
   matrix[x][y]=x+y;

共有6个答案

越俊驰
2023-07-03

cpu预加载缓存行的问题,二维数组在内存中是一个一维数组的数组结构,横向遍历是一个数组,是一块连续的存储空间,cpu预加载会加载一个缓存行的数据,根据操作系统不同有不同的大小,一般是64字节,横向遍历数据大多都在同一缓存行,在同一个缓存行修改就会很快;纵向遍历的话要加载下一个Y向的值要读取好多暂时用不到的数据,也可能会多次跨缓存行。效率就很慢
image.png
这个例子也是缓存行的一个例子,不添加填充字段和添加填充字段效率也有较大差异

严宏旷
2023-07-03

只看时间复杂度上的估计,肯定是一样的

感觉要关注二维数据在java存储的内存中的地址?

仇正平
2023-07-03

不太理解你的问题, 这两个的时间复杂度是一样的O(n^2)

本文参与了 SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
汪深
2023-07-03

示例不如这么写

for(int x=0;x<size;x++)
    for(int y=0;y<size;y++)
      matrix[x][y]=x+y; // matrix[y][x]=x+y;

为什么二维数组横向遍历比纵向遍历快?

那鹏
2023-07-03

不管是几维数据他的底层内存结构都是一维的,再加上大部分语言数组是按行存储的,在内存中所以一行的数据后面存储的就是他的下一行,cpu在取数据是会把数据先从内存中取到缓存中(比如L1)如果L1缓存一个缓存行是64byte,再加上现代cpu会对数据进行预取,那么第一种中没16次访存操作都是命中缓存,所以会比第二种快很多,由于1M的大小大概率不会超过CPU的三缓存(比如5950x有64M的三级缓存8M的二级缓存)这两个循环的速度就可以简单的等价于2级缓存和1级缓存速度之间的差距
第二种为啥慢应为他的访存模式导致他每次访存操作都会被映射到不同的缓存行比如
matrix[0][0]
matrix[1][0]
他们属于不同的缓存行而且就算L1缓存有几百K但是由于这种访存模式之前的数据就算加载到了缓存中,也会被后面的数据驱除出缓存也就是说每次从L2中加载了一个缓存行(64个字节)到L1中的只命中了4个字节,而第一种访存方式除了第一次冷缺失其他访存会全部命中L1,前面我们说过matrix[0][0]~matrix[0][16]是连续存储的会被放到同一个缓存行这也是为啥第一种快的原因,下面这张图说明的L1和L2的速度差距
image.png

符俊材
2023-07-03

第一反应是这是个锤子问题,能有啥差距,一跑还真是差距明显
image.png
第一反应是字节码有啥骚操作
image.png除了取值换了下 确实没啥差异
然后画了个图 - - 第一个数据跳过,如果是取第二个数据的时候,一维数组因为是连续内存,取值上面来说array0应该是是要快于array1的
image.png

 类似资料:
  • 所以我想看看有没有办法循环这些数组,看看哪一个与main函数中提供的{6,1,1,6,3,1,4,7,7,1}的数组匹配。

  • 本文向大家介绍请快速答出此题的答案并解释:var x, y = 1; x + y = ?相关面试题,主要包含被问及请快速答出此题的答案并解释:var x, y = 1; x + y = ?时的应答技巧和注意事项,需要的朋友参考一下 @t532 第一条规则 >若任何一侧是 string 或 object 则两边转换为 string 进行连接 关于object不是准确的。 举例: 按照ES标准规则,h

  • 我有一个的数组,它的值不同,称为。我想创建一个二维数组(称为),其中第一个维度的大小是数组的长度,第二个维度的大小是该索引处的整数值。我希望下面的代码能更容易理解我的问题。 我的实际代码,sizes数组更大,所以如果可能的话,我希望避免大量重复的代码行。 我是的新手,但我读过关于的文章。我想我可以创建一个函数来返回这个数组,但是我还没有让它工作。 我还认为我可以循环数组,并为每个创建一个具有该大小

  • 问题内容: 几年前我有这个面试问题,但是我还没有找到答案。 做无限循环的x和y应该是什么? 我们试着用,, VS 。 问题答案: 您需要两个可比较,具有相同值但代表不同实例的变量,例如: 和都为true,因为取消了装箱,但是实例相等性为false。 请注意,它也可以与一起使用,并且任何值(不仅是0)都可以使用。 您还可以使用JVM的复杂性-它们通常仅缓存最多127个整数,因此也可以使用: (但是1

  • 问题内容: 好的,所以我有一个二维数组z [50][50],因此z的大小是50*50,但是如果我说z.length,我只能得到50。如何获得2D数组的实际大小? 问题答案: 在Java中,二维数组实际上是长度可能不同的数组的数组(不能保证在二维数组中第二维数组的长度都相同) 您可以将任何第二维数组的长度作为where 。 如果将二维数组视为矩阵,则可以简单地获取和,但是请注意,您可能会假设第二维的

  • 本文向大家介绍Java中增强for循环在一维数组和二维数组中的使用方法,包括了Java中增强for循环在一维数组和二维数组中的使用方法的使用技巧和注意事项,需要的朋友参考一下 一维数组: 输出:1 2 3 二维数组: 输出: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 以上就是小编为大家带来的Java中增强for循环在一维数组和二维数组中的使用方法的全部内容了,希望对大家有所帮助,