Java:多维数组与一维数组 [英] Java: Multi-dimensional array vs. one-dimensional

查看:35
本文介绍了Java:多维数组与一维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如:

  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆