【发布时间】:2015-04-10 15:34:04
【问题描述】:
我了解在 Java 中处理二维数组时,您在循环中访问数组元素的顺序会影响遍历数组所需的时间:
int size = 500;
int[][] array = new int[size][size];
// Slower
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
array[j][i] = 1;
}
}
// Faster
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
array[i][j] = 1;
}
}
这对我来说很有意义,因为它需要更少的内存跳转,而是可以直接跳转到后续地址。
当对 3 维数组做同样的事情时,我对结果有点困惑:
Time: 12356332 nanoseconds. ([i][j][k])
Time: 18278948 nanoseconds. ([i][k][j])
Time: 13985288 nanoseconds. ([j][i][k])
Time: 126192723 nanoseconds. ([j][k][i])
Time: 39441820 nanoseconds. ([k][i][j])
Time: 156352618 nanoseconds. ([k][j][i])
[i][j][k] 和 [j][i][k] 的结果在大多数代码运行中是可互换的。这是为什么呢?
另外,您能否解释一下多维数组在 Java 中是如何存储的?
给定数组int[][][] array = new int[2][2][2],内存地址是否会像这样(我的理解是每个块之间可能还有其他变量的附加数据,但我省略了这些情况,因为它们不相关 em>):
(对不起,如果图像令人困惑,我只有油漆可以使用,并试图尽可能地表达布局。所以array[0][0][0] //[i][j][k] 将在地址06 中)
【问题讨论】:
-
你是如何测量这个的?在 Java 中准确测量这些东西的性能(甚至对于“A 比 B 更好”来说足够准确)真的非常困难。
-
我在每个循环前后都使用了
System.nanoTime()并减去了差异 -
是的,不,这不会为您提供准确的结果。如果您想获得可以实际告诉您 A 更快/更慢/等于 B 的测量值,请使用 JMH 或 Caliper。
-
Java 实现数组的技术术语是锯齿状数组。见en.m.wikipedia.org/wiki/Jagged_array