我正在使用大量数据,这些数据正在从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
。地图可能是不变的,但访问性能至关重要。
读取和存储数据与读取和丢弃数据之间的比较是不公平的,因为它不会在内存分配器上加载。您可以通过运行以下实验快速看到:
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;
}
}
既然您将实体保留而不是将其扔掉,那么时机就会更接近在哈希地图中存储实体的时机。由于存储实体在数组中是一个几乎瞬时的操作,因此在上述运行的时间表之上,您无法实现太多改进。
如果@dasblinkenlight是正确的(我认为他是!(关于内存分配和垃圾收集是真正的瓶颈,那么您可以通过使用较大的初始初始和较大的初始和最大堆尺寸;例如使用-Xms
和-Xmx
选项。但是,这也可能无济于事。
但是没有更快的方法来执行HashMap
插入。您已经在做一件事(在您的代码中(会有所作为。