实现HashMap插入的高吞吐量

时间:2017-06-29 12:27:40

标签: java performance hashmap

我正在处理大量数据,这些数据正从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可能是不可变的,但访问性能至关重要。

2 个答案:

答案 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插入。你已经做了一件事(在你的代码中)会产生影响。