列出使用double 的RAM的?

Java专家强调避免过早优化的重要性,而是专注于清洁OO设计。 我试图在重写使用大量长元素(几百万)的程序的上下文中调和这个原则。 看起来使用ArrayList会占用long的原始数组的大约3倍的内存,并且浪费那么多RAM似乎是我的合理关注。

我的基础是我使用此处描述的 MemoryTestBench类进行的实验。 我的测试和输出如下:

package memory; import java.util.ArrayList; import java.util.List; public class ArrayListExperiment { public static void main(String[] args) { ObjectFactory arrayList = new ObjectFactory() { public Object makeObject() { List temp = new ArrayList(1000); for (long i=0; i<1000; i++) temp.add(i); return temp; } }; ObjectFactory primitiveArray = new ObjectFactory() { public Object makeObject() { long[] temp = new long[1000]; for (int i=0; i<1000; i++) temp[i] = i; return temp; } }; MemoryTestBench memoryTester = new MemoryTestBench(); memoryTester.showMemoryUsage(primitiveArray); memoryTester.showMemoryUsage(arrayList); } } 

并输出:

 memory.ArrayListExperiment$2 produced [J which took 8016 bytes memory.ArrayListExperiment$1 produced java.util.ArrayList which took 24968 bytes 

我的问题是:我如何获得OO列表的好处并仍然保留原始数组的小内存占用? 我认为guava可能提供了答案,但是通过API浏览我并不明白使用哪个类来代替ArrayList。

谢谢你的任何建议。

您可以考虑使用Trove ,它提供对原始集合的支持,例如TDoubleArrayList类:

一个可resize的,由数组支持的双基元列表。

编辑:这个类确实没有实现List ,但这是Java避免盒装基元的代价。 Guava的解决方案是最通用的,而Trove最适合更极端的性能要求。

我认为你在Guava中寻找的是Doubles.asList

我认为您正在寻找FastUtil的 DoubleArrayList – 它由原始数组支持。

如果您的集合非常大(大于2 ^ 31个元素),您可能还想查看他们的BigArrays

编写自己的ArrayList实现,它使用一个基元数组。 复制当前的ArrayList代码并用double []替换内部Object []。

应该是一个非常直接的复制和替换。

编辑:对内存消耗的最大危险将是“增长”。 它会占用至少两倍的空间,再加上你增长的额外空间。 如果您无法预先调整数组大小以避免这种情况,您可能需要考虑使用多个数组的稍微不同的实现,因为它随着时间的推移而增长。 关于插入和索引的更多数学,但不应该太糟糕。

Arrays.asList(T …)可能就是你要找的东西。 它返回由传递给它的数组支持的List实例。

这是一个很好的问题 – 性能与代码清洁度。 我认为你有理由不那么关心清洁OO设计,只关注为大量长期工作的具体问题创建一个很好的解决方案。 如果这样做,将面向性能的代码保存在一个类/包中将最大限度地减少其对整体设计的影响。 假设管理大量的多头只是一个更大的应用程序的一小部分……