3

我不是 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,否则我会得到一个空指针异常。这意味着new第 1 行还不够。P[i][j]=n考虑到数组也是 Java 中的对象,这是否比为了争论而更昂贵的操作?

4

4 回答 4

4

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

但是,只有分析才能判断在您的情况下它是否值得优化。

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

于 2013-03-23T10:45:50.890 回答
2

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

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

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

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

于 2013-03-23T10:54:30.103 回答
1

为了快速处理真正大量的数据,最好将数据放置在单个连续的内存块中,这样您一起访问的数据彼此靠近。这应该最大限度地减少缓存未命中,这是当今最糟糕的性能杀手之一。

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

另一个稍微复杂的解决方案是使用堆外数据结构,如下所示:http: //mechanical-sympathy.blogspot.com/2012/10/compact-off-heap-structurestuples-in.html

于 2013-03-24T09:09:35.837 回答
0

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

此外,在运行时分配内存(即使用 new 关键字)非常昂贵,然后只需将值分配给已经存在的对象,即 p[i][j]=v;

于 2013-03-23T10:44:59.830 回答