Java:多维数组 - 哪个维度先行?

时间:2011-11-06 18:29:10

标签: java arrays performance multidimensional-array

java中这两个数组之间是否有任何性能差异(可能与J2ME开发有关...):

String[][][] a = //for getting an entry by a[group][person][field]
    {
        { // group A:
            {"John", "Doe", "teacher", "New York"},
            {"Donald", "Duck", "jinx", "Duckburg"},
            // 10 or more further entries
        },
        { // group B:
            {"Barack", "Obama", "president", "Washington"},
            // ...
        }
    };
String[][][] b = //for getting an entry by b[field][group][person]
    {
        { // prenames:
            {"John", "Donald", ...},
            {"Barack", ...}
        },
        { // surnames:
            {"Doe", "Duck", ...},
            {"Obama", ...}
        },
        { // job:
            {"teacher", "jinx", ...},
            {"president", ...}
        },
        { // city:
            {"New York", "Duckburg", ...},
            {"Washington", ...}
        }
    };

我猜第二个数组的性能更高,因为它总共包含较少的嵌套数组,而第一个数组每个人都有一个数组!在更大的阵列上传输这个......

感谢您的回答!

更新

更好(现实)的例子是一个数组,比方说,1000 x / y坐标:

int[][] coordsA =
    {
        {0, 0},
        {2, 7},
        {8, 2},
        {4, 2},
        {-3, 15},
        {1, 32},
        // ...
    };
int[][] coordsB =
    {
        {0, 2, 8, 4, -3, 1, ...}, // x values
        {0, 7, 2, 2, 15, 32, ...} // y values
    }

2 个答案:

答案 0 :(得分:3)

多年前,当我使用Fortran时,我们被告知要在多维数组上安排我们的循环,以便第一个维度是因为内存排列方式而迭代最快的那个,并且会导致更少页面错误。

然而,从那时起,我已经在Java中学到了(就像几乎所有内容一样),如果你性能问题,你应该测量所有提议解决方案,直到找到不再存在性能问题的解决方案。过早优化是万恶之源等等。

如果您认为阵列数量存在问题,您是否测量了每个选项所占用的内存量?你有没有测量过特定操作所需的时间。

如果您没有性能问题,请使用最符合您要求的表示法。

答案 1 :(得分:1)

<insert usual knuth quote, etc. here - but I assume anyone here knows that already anyhow>

Java的问题是每个数组级别本身都被视为一个对象,即我们没有为我们的数组获得连续的内存区域(GC可以帮助我们)

这有几个影响:

  • 更糟糕的缓存位置
  • 每个阵列级别的附加边界检查
  • 访问一个元素所需的额外内存访问

不是很好(即在最坏的情况下,而不是对一个元素有一个内存访问,我们可能得到2 *索引级别的内存访问),所以通常的解决方案,如果你需要有效的数组是只创建一个大数组并自己做索引。这避免了所有这些问题,代价是需要一些简单的辅助方法(这非常简单,特别是如果所有子数组都具有相同的大小)。

性能提升在很大程度上还取决于您的访问方案。如果你想要比较帖子中给出的两个不同的变体,它可能没那么重要(例如,如果你正确地命令你的数组,你在C或co中获得的相同增益)。在它们的子数组中按顺序访问它们仍应提供更好的缓存局部性。