Java:多维数组与一维数组 [英] Java: Multi-dimensional array vs. one-dimensional
问题描述
例如:
a)
int [x][y][z]
对比
b) int[x*y*z]
最初以为我会选择 a) 为简单起见.
Initially thought I'd go with a) for simplicity.
我知道 Java 不像 C 那样在内存中线性存储数组,但这对我的程序有什么影响?
I know that Java doesn't store arrays linearly in memory like C does, but what implications does this have for my program?
推荐答案
在搜索此类问题的答案时,通常最好的做法是查看这些选项是如何编译成 JVM 字节码的:
Usually the best thing to do when searching anwers for such questions is to see how the choices are compiled into JVM bytecode:
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 已经知道我们在谈论一个多维数组.
So, as you can see, the JVM already knows that we are talking about a multi dimensional array.
更进一步:
for (int i = 0; i < 50; ++i)
for (int j = 0; j < 50; ++j)
{
multi[i][j] = 20;
single[i*50+j] = 20;
}
这被翻译成(跳过循环):
This is translated (skipping the cycles) into:
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 内部处理,没有无用指令产生的开销,而使用单个会使用更多指令,因为偏移量是手动计算的.
So, as you can see, the multi-dimensional array is treated internally in the VM, no overhead generated by useless instructions, while using a single one uses more instructions since offset is calculated by hand.
我认为性能不会成为这样的问题.
I don't think that performance will be such an issue.
我做了一些简单的基准测试,看看这里发生了什么.我选择尝试不同的例子:线性阅读,线性写入,和随机访问.时间以毫秒表示(并使用 System.nanoTime()
计算.结果如下:
I did some simple benchmarks to see what's going down here.
I chose to try different examples:
linear read,
linear write,
and random access.
Times are expressed in millisecs (and calculated using System.nanoTime()
.
Here are the results:
线性写入
- 尺寸:100x100 (10000)
- 多:5.786591
- 单身:6.131748
- 多:1.216366
- 单:0.782041
- 多:7.177029
- 单身:3.667017
- 多:30.508131
- 单身:18.064592
- 多:185.3548
- 单身:155.590313
- 多:955.5299
- 单身:923.264417
- 多:4084.798753
- 单身:4015.448829
线性读取
- 尺寸:100x100 (10000)
- 多:5.241338
- 单身:5.135957
- 多:0.080209
- 单:0.044371
- 多:0.088742
- 单:0.084476
- 多:0.232095
- 单:0.167671
- 多:0.481683
- 单:0.33321
- 多:1.222339
- 单:0.828118
- 多:2.496302
- 单:1.650691
随机读取
- 尺寸:100x100 (10000)
- 多:22.317393
- 单身:8.546134
- 多:32.287669
- 单身:11.022383
- 多:189.542751
- 单身:68.181343
- 多:1124.78609
- 单身:272.235584
- 多:6814.477101
- 单身:1091.998395
- 多:50051.306239
- 单身:7028.422262
随机数有点误导,因为它为多维数组生成 2 个随机数,而为单维生成一个随机数(并且 PNRG 可能会消耗一些 CPU).
The random one is a little misleading since it generates 2 random numbers for multi-dimensional array while just one for single dimensional (and PNRGs may consume some CPU).
请注意,我仅在同一循环的第 20 次运行后才尝试通过基准测试来让 JIT 工作.为了完整起见,我的 Java VM 如下:
Mind that I tried to let JIT work by benchmarking only after the 20th run of the same loop. For completeness my java VM is the following:
java 版本1.6.0_17"Java(TM) SE 运行时环境(构建 1.6.0_17-b04)Java HotSpot(TM) 64 位服务器 VM(构建 14.3-b01,混合模式)
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:多维数组与一维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!