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