在大型Java集合中添加性能瓶颈

在大型Java集合中添加性能瓶颈,java,performance,collections,Java,Performance,Collections,我正在尝试向列表中添加一百万个对象。做这件事所需的时间比我耐心等待的时间还要长。似乎每一步都要花费越来越长的时间 int size = 1000000; Deque<DatastoreElement> content = new LinkedList<DatastoreElement>(); for (int i = 0; i < size; i++) { String k = Utils.getRandomStringO

我正在尝试向列表中添加一百万个对象。做这件事所需的时间比我耐心等待的时间还要长。似乎每一步都要花费越来越长的时间

    int size = 1000000;
    Deque<DatastoreElement> content = new LinkedList<DatastoreElement>();

    for (int i = 0; i < size; i++) {

        String k = Utils.getRandomStringOfLength(20);
        String v = Utils.getRandomStringOfLength(300); // goes faster with smaller number

        int metaHash = random.nextInt(10) + 1;
        KVPair kvp = new KVPair(k, v);
        DatastoreElement dse = new DatastoreElement(metaHash, kvp);

        content.addLast(dse); // confirmed problem is here

        if (i % 10000 == 0) {
            System.out.println(i);
        }
    }
int size=1000000;
Deque content=new LinkedList();
对于(int i=0;i
我尝试将内容添加到
列表
集合
,结果非常相似。它启动得很快,过了一段时间就窒息了


我应该使用什么集合来存储大量的相似元素?我是不是遗漏了一些简单的东西?

这个问题不是一般的集合,也不是如图所示的
LinkedList
(它具有
O(1)
添加特性)

因此,可能的嫌疑犯是对内存的重击/交换。确保JVM有足够的内存,并且系统有更多的内存

LinkedList
切换到
ArrayList
(或
ArrayDeque
)将保持
O(1)
摊销绩效,但可能会每个项目的开销略少。(开销,以及这种减少是否重要,取决于添加的对象的大小和支持存储的填充率。)

  • 已经建议使用ArrayList(在链接列表中,每个项/节点都意味着一个附加对象)
  • 另外(以前也建议过),如果使用基于数组的集合,请尝试构造/调整大小到适当的长度
  • 此外,如果内存有问题,您可能希望将Flyweight模式与string元素
    string#intern()
    一起使用,以便收集冗余实例

尝试为1000000个元素预先分配的
ArrayList
答案取决于您打算如何使用数据。除非您需要能够在两个方向上进行迭代,否则请使用
ArrayList
而不是
LinkedList
。一旦你加载了一百万个对象,你会用它们做什么?也许JVM是垃圾。尝试使用以下命令增加内存限制:-mx@Jam我非常怀疑
数组列表中添加
元素会造成严重的瓶颈。你确定瓶颈不是在制作对象本身吗?@Jam为了把问题归结到一个特定的调用,我建议你尝试用一个合适的分析器来分析你的代码,例如jdk附带的JVisualVM实际上
LinkedList
总是会更糟糕,因为内存节点不是像
ArrayList
中那样可以缓存在同一个目录中的连续内存pages@Cratylus这是JVM要处理的:)反例可能在“backing double”之后填充率约为50%的操作。但是如果没有一些测试,我也不会赌钱..JVM?你认为JVM会对大小为
X
的节点的请求进行这种优化吗?
ArrayList
在内存位置上几乎肯定会比
LinkedList
更好。现在使用简单的数组,使用
Xmx1024m
。工作起来很有魅力。非常感谢。