Java 数组效率

3

我不完全确定机制是如何运作的,所以我决定在这里发帖进行进一步澄清。

我正在使用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行中的 new 不足以完成此操作。相对于 Java 中数组也是对象,这是否比如 P[i][j]=n 之类的更昂贵?


我认为 v[i][j] = new MyObject(object1 , object2); 比 P[i][j]=n; 更昂贵。但我不认为你必须对此如此严肃。 - Achintya Jha
在开始编码之前,弄清不同内存布局的效率从来都是行不通的。你应该选择其中一种方式进行编码,然后进行性能分析。如果速度太慢,看看是什么导致了减速;很可能与对象在内存中的布局无关。 - Sergey Kalinichenko
1
如果n远大于或小于m:https://dev59.com/questions/rWUp5IYBdhLWcg3wVWiv - assylias
更新:我没有进行任何空间分析,但是我的代码使用数组运行速度快了两倍,所以我会坚持使用它们。 - user2002121
4个回答

4

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

但是,只有分析才能告诉您在您的情况下是否值得进行此优化。

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


2
相较于 P[i][j]=n,这是否是一个更昂贵的操作,考虑到数组在Java中也是对象?
在第一种情况下,您需要创建一个数组对象来存储其他类型为数组的对象。数组对象和将要存储在数组中的对象都需要实例化,这意味着您需要 m * n + 1 次对象实例化以及 (m * n + 1) * objectSize 内存消耗。
在第二种情况下,您只需要实例化数组对象;int原语不是对象,因此这应该更快,而且内存效率更高,因为Object内存大小是int的几倍。在这里,您基本上只有一个对象实例化和(m * n) * intSize + objectSize 的内存消耗。
使用原语的另一个原因是,当作为局部变量使用时,它们保留在堆栈上;您可能会在方法中使用中间本地变量,然后在数组中存储计算出的值,在这种情况下,这些变量的内存分配/释放时间比生存于堆上的对象要高出几倍。

对象的内存消耗真的比两个原始类型变量大那么多吗?根据我的理解,为对象分配的空间将包括其两个原始类型字段以及一些额外开销。这是根据http://www.javamex.com/tutorials/memory/object_memory_usage.shtml上的说明。为什么会“几倍”地更大呢? - user2002121
@user2002121 整数对象占用四倍的空间;预计对象将占用三倍的空间(因为它没有int)- 请参阅可靠的参考资料:http://www.ibm.com/developerworks/java/library/j-codetoheap/index.html 还要注意的是,他不能将对象对象用于任何事情(例外情况是用于同步锁,但不适用于此情况)。 - Random42

1
为了快速处理大量数据,最好将数据以一种使你访问的数据靠近彼此的方式放在单个连续的内存块中。这应该最小化缓存未命中,这是当今最糟糕的性能杀手之一。
在Java中,您可以通过仅使用一个单一的一维原始数组来实现这一点。如果您使用两个数组甚至是二维数组,则不能保证数据仍然位于一个连续的块中。
另一个稍微复杂的解决方案是使用堆外数据结构,例如:http://mechanical-sympathy.blogspot.com/2012/10/compact-off-heap-structurestuples-in.html

0
首先,您必须在Java中使用List或Set即集合而不是数组。因为您可能不知道需要处理的数据大小。此外,集合具有API方法,允许您轻松执行插入元素或删除元素等操作。使用数组的工作非常复杂且容易出错,因为您可能需要一遍又一遍地迭代它,并且大小必须在编译时确定,如果您具有可变大小数据,则不可能。
此外,在运行时分配内存(即使用new关键字)比仅将值分配给已存在的对象昂贵,即p [i] [j] = v;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接