例如:
a)
int [x][y][z]
对
b)
int[x*y*z]
为了简单起见,我最初认为我会选择 a)。
我知道 Java 不像 C 那样将数组线性存储在内存中,但这对我的程序有什么影响?
最佳答案
在搜索此类问题的答案时,通常最好的办法是查看这些选项是如何编译成 JVM 字节码的:
multi = new int[50][50];
single = new int[2500];
这被翻译成:
BIPUSH 50
BIPUSH 50
MULTIANEWARRAY int[][] 2
ASTORE 1
SIPUSH 2500
NEWARRAY T_INT
ASTORE 2
所以,如您所见, JVM 已经知道我们说的是多维数组。
继续下去:
for (int i = 0; i < 50; ++i)
for (int j = 0; j < 50; ++j)
{
multi[i][j] = 20;
single[i*50+j] = 20;
}
这被翻译(跳过循环)成:
ALOAD 1: multi
ILOAD 3: i
AALOAD
ILOAD 4: j
BIPUSH 20
IASTORE
ALOAD 2: single
ILOAD 3: i
BIPUSH 50
IMUL
ILOAD 4: j
IADD
BIPUSH 20
IASTORE
所以, 如你看到的, 多维数组在 VM 内部处理, 没有无用指令产生的开销, 而使用单个则使用更多指令,因为偏移量是手动计算的。
我认为性能不会成为这样的问题。
编辑:
我做了一些简单的基准测试来看看这里发生了什么。
我选择尝试不同的例子:
线性读取,
线性写入,
和随机访问。
时间以毫秒表示(并使用 System.nanoTime()
计算。
结果如下:
线性写入
- 尺寸:100x100 (10000)
- 多个:5.786591
- 单例:6.131748
- 尺寸:200x200 (40000)
- 多路:1.216366
- 单人:0.782041
- 尺寸:500x500 (250000)
- 多路:7.177029
- 单例:3.667017
- 尺寸:1000x1000 (1000000)
- 多个:30.508131
- 单例:18.064592
- 尺寸:2000x2000 (4000000)
- 多路:185.3548
- 单例:155.590313
- 尺寸:5000x5000 (25000000)
- 多路电话:955.5299
- 单例:923.264417
- 尺寸:10000x10000 (100000000)
- 多个:4084.798753
- 单例:4015.448829
线性读取
- 尺寸:100x100 (10000)
- 多路:5.241338
- 单例:5.135957
- 尺寸:200x200 (40000)
- 多:0.080209
- 单人:0.044371
- 尺寸:500x500 (250000)
- 多:0.088742
- 单个:0.084476
- 尺寸:1000x1000 (1000000)
- 多:0.232095
- 单人:0.167671
- 尺寸:2000x2000 (4000000)
- 多:0.481683
- 单人:0.33321
- 尺寸:5000x5000 (25000000)
- 多路:1.222339
- 单例:0.828118
- 尺寸:10000x10000 (100000000)
- 多路:2.496302
- 单例:1.650691
随机读取
- 尺寸:100x100 (10000)
- 多个:22.317393
- 单例:8.546134
- 尺寸:200x200 (40000)
- 多个:32.287669
- 单例:11.022383
- 尺寸:500x500 (250000)
- 多:189.542751
- 单例:68.181343
- 尺寸:1000x1000 (1000000)
- 多:1124.78609
- 单例:272.235584
- 尺寸:2000x2000 (4000000)
- 多路电话:6814.477101
- 单例:1091.998395
- 尺寸:5000x5000 (25000000)
- 多个:50051.306239
- 单例:7028.422262
随机数有点误导,因为它为多维数组生成 2 个随机数,而为一维数组生成一个随机数(PNRG 可能会消耗一些 CPU)。
请注意,我试图让 JIT 仅在同一循环的第 20 次运行后进行基准测试。为了完整起见,我的 java VM 如下:
java version "1.6.0_17" Java(TM) SE Runtime Environment (build 1.6.0_17-b04) Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)
关于Java:多维数组与一维,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2512082/