列出使用double []?</double>的RAM的<double>

时间:2011-12-21 06:37:00

标签: java data-structures guava

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

我基于使用MemoryTestBench类described here进行的实验。我的测试和输出如下:

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<Long> temp = new ArrayList<Long>(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。

感谢您的任何建议。

6 个答案:

答案 0 :(得分:16)

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

答案 1 :(得分:11)

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

  

可调整大小的,由数组支持的双基元列表。

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

答案 2 :(得分:5)

我认为您正在寻找FastUtil's DoubleArrayList - 它由原始数组支持。

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

答案 3 :(得分:3)

编写自己的ArrayList实现,该实现使用基元数组。复制当前的ArrayList代码,并用双[]。

替换内部Object []

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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