我正在处理大量数据,这些数据正从HDD中读取并放入HashMap
。使用Externalized
代替Serializable
优化了阅读流程,因此实际数据量不是问题。
此过程中的瓶颈是HashMap<Long, Entity>
,它在此过程中填充。我的代码如下:
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
int nbEntries = in.readInt();
entities = new HashMap<>(nbEntries);
for(int i = 0; i < nbEntries; i++) {
Entity entity = new Entity(0);
relation.readExternal(in);
//entities.put(entity.getId(), entity); //<-- Bottleneck!
}
}
正如比较:阅读4Gb数据需要 93 秒,包括插入HashMap
和 14 秒而不插入。
是否有快速方法可将大量数据插入HashMap
?数据不必保持HashMap
。 Map可能是不可变的,但访问性能至关重要。
答案 0 :(得分:1)
读取和存储数据与读取和丢弃数据之间的比较是不公平的,因为它不会给内存分配器带来任何负担。您可以通过运行以下实验快速查看:
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
int nbEntries = in.readInt();
Entity[] entities = new Entity[nbEntries];
for(int i = 0; i < nbEntries; i++) {
Entity entity = new Entity(0);
relation.readExternal(in);
entities[i] = entity;
}
}
既然你保留了你的实体而不是扔掉它们,那么时间就会更接近于在哈希映射中存储实体的时间。由于在数组中存储实体几乎是瞬时操作,因此在上述运行时间之外,您无法实现很多改进。
答案 1 :(得分:1)
如果@dasblinkenlight是正确的(我认为他是!)关于内存分配和垃圾收集是真正的瓶颈,那么你可以通过使用更大的初始和最大堆大小来改善加载时间;例如使用-Xms
和-Xmx
选项。但是,这也可能无济于事。
但是没有更快的方法来执行HashMap
插入。你已经做了一件事(在你的代码中)会产生影响。