Java阵列效率

Java阵列效率,java,multidimensional-array,performance,memory-efficient,Java,Multidimensional Array,Performance,Memory Efficient,我不是100%确定的机制在行动,所以我决定张贴在这里进一步澄清 我正在做一个用Java处理大量数据的项目(必须是Java)。我希望它尽可能高效。所谓高效,我的意思是内存和速度计算应该排在第一位,可读性应该排在第二位 现在我有两种存储数据的方法:创建一个MyObject 1) MyObject[][] V = new MyObject[m][n] 或创建两个int数组: 2) int[][] V = new int[m][n] 3) int[][] P = new int[m][n] 显然,

我不是100%确定的机制在行动,所以我决定张贴在这里进一步澄清

我正在做一个用Java处理大量数据的项目(必须是Java)。我希望它尽可能高效。所谓高效,我的意思是内存和速度计算应该排在第一位,可读性应该排在第二位

现在我有两种存储数据的方法:创建一个
MyObject

1) MyObject[][] V = new MyObject[m][n]
或创建两个int数组:

2) int[][] V = new int[m][n]

3) int[][] P = new int[m][n]

显然,
MyObject
至少包含两个字段和一些方法。现在我注意到,在
MyObject
数组上循环赋值时,我必须调用
new
,否则会出现空指针异常。这意味着第1行中的
不够。考虑到数组也是Java中的对象,这是一个比(
P[i][j]=n)更昂贵的操作吗?

首先,您必须使用Java中的列表或集合,即集合,而不是数组。因为您可能不知道需要处理的数据的大小。此外,集合具有API方法,允许您轻松执行插入元素或删除元素等操作。使用数组非常复杂且容易出错,因为您可能需要一次又一次地对它进行迭代,而且大小必须在编译时确定,如果您有可变大小的数据,这是不可能的


此外,在运行时分配内存(即使用new关键字)比仅将值分配给已经存在的对象(即p[i][j]=v)更昂贵

我经常通过分析发现,用几个标量数组替换一个对象数组可以提高内存消耗和性能

然而,只有分析才能判断在您的案例中它是否是一个值得优化的优化

一个好的分析器可以让您测量代码的性能和内存占用

考虑到数组也是Java中的对象,这是一个比p[i][j]=n更昂贵的操作吗

在第一种情况下,创建一个数组对象,用于存储其他类型的数组对象。数组对象和要存储在数组中的对象都需要实例化,这意味着您需要
m*n+1
对象实例化以及
(m*n+1)*objectSize
内存消耗

在第二种情况下,只需实例化数组对象;int原语不是对象,因此这应该更快,内存效率也更高,因为对象内存大小是int的几倍。这里基本上有1个对象实例化和
(m*n)*intSize+objectSize
内存消耗


使用原语的另一个原因是,当用作局部变量时,它们保留在堆栈上;在将计算值存储到数组中之前,您可能会在方法中使用中间局部变量,这些变量的内存分配/解除分配时间比堆中对象的内存分配/解除分配时间高出数倍。

要快速处理真正海量的数据,最好将数据放在单个连续的内存块,使您一起访问的数据彼此接近。这将最大限度地减少缓存未命中,缓存未命中是当今性能最差的杀手之一

在java中,您可以通过只使用一个一维基元数组来实现这一点。如果使用两个数组甚至二维数组,则不再保证数据位于一个连续块中


另一个稍微复杂的解决方案是使用堆外数据结构,如下所示:

我认为是v[I][j]=newmyobject(object1,object2);比P[i][j]=n;更贵。但我认为你不必对这件事太认真。在开始编码之前先弄清楚不同内存布局的效率是行不通的。无论采用哪种方式,您都应该从两种方式中选择一种进行编码,然后配置文件。如果太慢,看看是什么让你慢下来;很可能,它与内存中对象的布局无关。相关,如果n明显大于或小于m:Update:我没有进行任何空间分析,但我的代码在数组中运行速度快两倍,因此我将坚持使用这些。对象内存消耗真的比两个原语大那么多吗?根据我的理解,分配给对象的空间将由它的两个基本字段和一些开销组成。这是根据为什么它会“几倍”大?@user2002121一个整数对象占用的空间是原来的四倍;一个对象需要占用三倍多的空间(因为它没有int)-请参阅可靠参考:还要注意的是,他不能将对象对象用于任何事情(例外是用于同步的锁,本例中没有)。