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

Jon*_*nah 20 java guava data-structures

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<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);
}
}
Run Code Online (Sandbox Code Playgroud)

并输出:

memory.ArrayListExperiment$2 produced [J which took 8016 bytes
memory.ArrayListExperiment$1 produced java.util.ArrayList which took 24968 bytes
Run Code Online (Sandbox Code Playgroud)

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

谢谢你的任何建议.

小智 16

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

  • @TimothyJones:`Arrays.asList`不适用于原始数组...传入`double []`并得到一个单元`List <double []>`. (7认同)
  • @Jonah:显然会有一些性能上的差异,所以如果你真的只需要用Java可能获得的绝对最快的速度(也许你可以),那么直接使用数组就是唯一的选择.Trove选项也可能更快一些,因为它没有实现`List`,因此可以在其API中使用原始类型.顺便说一下,你应该使用`System.nanoTime()`进行基准测试. (4认同)
  • 同意.如果你需要List接口,Guava是你要找到的最好的,如果没有,那么你应该直接使用Trove或数组. (3认同)

Pau*_*ora 11

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

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

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

  • ...另一方面它没有实现`List`接口;) (3认同)

Tim*_*nes 5

我认为你正在寻找FastUtil DoubleArrayList - 它由一个原始数组支持.

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