2D阵列分配的性能

Kat*_*ona 6 java arrays performance

我想知道为什么一次分配2D int数组(new int[50][2])执行比分别分配更差,即new int[50][]先执行,然后new int[2]逐个执行.这是一个非专业的基准代码:

public class AllocationSpeed {

    private static final int ITERATION_COUNT = 1000000;

    public static void main(String[] args) {
        new AllocationSpeed().run();
    }

    private void run() {
        measureSeparateAllocation();
        measureAllocationAtOnce();
    }

    private void measureAllocationAtOnce() {
        Stopwatch stopwatch = Stopwatch.createStarted();
        for (int i = 0; i < ITERATION_COUNT; i++) {
            allocateAtOnce();
        }
        stopwatch.stop();
        System.out.println("Allocate at once: " + stopwatch);
    }

    private int allocateAtOnce() {
        int[][] array = new int[50][2];
        return array[10][1];
    }

    private void measureSeparateAllocation() {
        Stopwatch stopwatch = Stopwatch.createStarted();
        for (int i = 0; i < ITERATION_COUNT; i++) {
            allocateSeparately();
        }
        stopwatch.stop();
        System.out.println("Separate allocation: " + stopwatch);
    }

    private int allocateSeparately() {
        int[][] array = new int[50][];
        for (int i = 0; i < array.length; i++) {
            array[i] = new int[2];
        }
        return array[10][1];
    }
}
Run Code Online (Sandbox Code Playgroud)

我测试了64位linux,这些是不同的64位oracle java版本的结果:

1.6.0_45-B06:

Separate allocation: 401.0 ms
Allocate at once: 1.673 s
Run Code Online (Sandbox Code Playgroud)

1.7.0_45-B18

Separate allocation: 408.7 ms
Allocate at once: 1.448 s
Run Code Online (Sandbox Code Playgroud)

1.8.0-EA-B115

Separate allocation: 380.0 ms
Allocate at once: 1.251 s
Run Code Online (Sandbox Code Playgroud)

只是出于好奇,我也尝试使用OpenJDK 7(差异较小):

Separate allocation: 424.3 ms
Allocate at once: 1.072 s
Run Code Online (Sandbox Code Playgroud)

对我来说这是违反直觉的,我希望立刻分配更快.

Joo*_*gen 1

绝对难以置信。基准源可能会受到优化、gc 和 JIT 的影响,但这呢?

查看java字节码指令集

  • 对象类数组的anewarray(+ 2 字节间接类索引)(a = 地址)
  • newarray(+ 1 个字节用于原始类)用于原始类型的数组
  • 多维数组的multianewarray (+ 2 字节间接类索引)

这导致人们怀疑 multianewarray 对于原始类型来说并不是最优的。

在进一步研究之前,我希望有人知道我们在哪里被误导了。

  • 字节码几乎不会比源代码告诉我们更多关于速度的信息,因为是 JITC 决定了速度。 (3认同)