浏览 3982 次
锁定老帖子 主题:java中多维数组探讨及发散思考
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-12-10
ushort[, , ,] map = new ushort[3000, 3000, 3, 3]; 暂且先不管为啥要搞一个四维数组(毕竟四维已经超出了人的立体思维想象了-_-),我随手写了一个测试类来测试,但是发现了一个更有意思的现象,数组声明方式不同会导致初始化的效率极大区别: 声明方式一: int [][][][] map = new int[3000][3000][3][3]; 声明方式二: int [][][][] map2 = new int[3][3][3000][3000]; 方式一花费时间大概为13秒,方式二花费时间不到1秒,而且内存耗费前者为1158000K,后者为342320K,相差3倍。 文字描述就这些,下面直接看代码: public class MutipleArray { public static void main(String[] args) throws InterruptedException { long t0 = System.currentTimeMillis(); int [][][][] map = new int[3000][3000][3][3]; for (int i = 0; i < 3000; i++) for (int j = 0; j < 3000; j++) for (int k = 0; k < 3; k++) for (int l = 0; l < 3; l++) map[i][j][k][l] = 45001; long t1 = System.currentTimeMillis(); System.out.println("Time for initializing the first Array:"+(t1-t0)+"ms"); int [][][][] map2 = new int[3][3][3000][3000]; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) for (int k = 0; k < 3000; k++) for (int l = 0; l < 3000; l++) map2[i][j][k][l] = 45001; long t2 = System.currentTimeMillis(); System.out.println("Time for initializing the second Array:"+(t2-t1)+"ms"); Thread.sleep(10000); } } 结果: Time for initializing the first Array:13570ms Time for initializing the second Array:495ms 为什么同样容量的数组,效率却差别如此之大呢? 个人看法: 方式一: int [][][][] map = new int[3000][3000][3][3]; 其实相当于: int [][][][] map = new int[3000*3000*3][3]; 方式二: int [][][][] map2 = new int[3][3][3000][3000]; 相当于: int [][][][] map2 = new int[3*3*3000][3000]; 方式一需要JVM为map开辟3000*3000*3个内存大小为4个字节的3个连续空间。 方式二需要JVM为map1开辟3*3*3000个内存大小为4个字节的3000个连续空间,这一下子就把时间效率区别开了。但是为什么二者所占的内存大小却也相差3倍左右呢?没有继续探究,希望能抛砖引玉,大家在此讨论一下。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-12-10
其实这个与jvm中数组的内存模型有关系,int[3000][3000][3][3],其实相当于有3000 * 3000 * 3这么多的数组类对象,而int[3][3][3000][3000],只有3 * 3 * 3000这么多的数组类对象,基于这一点,使得两种方式在时间和空间上有显著的区别:
1)空间上的区别,要知道一个数组对象,除了存储数组信息,还有很多辅助的变量需要存储,具体多少可以参考JVM的实现,两者的空间区别就体现在这些辅助的变量空间上,哪怕只需要多一个字节去存储,在3000 * 3000 * 3这么大的基数上,也是会非常大的; 2)时间上的区别,也是因这个而起,每个对象的构建都需要花费一些时间,第一种方式需要构建3000 * 3000 * 3次,而第二种只需要3 * 3 * 3000次,所以时间上会有很大差异; 至于具体相差多少数值,空间上可以分析具体的对象内存可以得出,时间上没想到好的度量方法 |
|
返回顶楼 | |
发表时间:2012-12-10
iamiwell 写道 1)空间上的区别,要知道一个数组对象,除了存储数组信息,还有很多辅助的变量需要存储,具体多少可以参考JVM的实现,两者的空间区别就体现在这些辅助的变量空间上,哪怕只需要多一个字节去存储,在3000 * 3000 * 3这么大的基数上,也是会非常大的; 2)时间上的区别,也是因这个而起,每个对象的构建都需要花费一些时间,第一种方式需要构建3000 * 3000 * 3次,而第二种只需要3 * 3 * 3000次,所以时间上会有很大差异; 至于具体相差多少数值,空间上可以分析具体的对象内存可以得出,时间上没想到好的度量方法 说的有道理。 |
|
返回顶楼 | |
发表时间:2012-12-11
第一个想到的就是空间上的分配方式不同,不管是行向,还是纵向。
第二个可以立即想到的,二种不同的声明方式,意味着完全不同的逻辑意义。 |
|
返回顶楼 | |