实现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。地图可能是不变的,但访问性能至关重要。

读取和存储数据与读取和丢弃数据之间的比较是不公平的,因为它不会在内存分配器上加载。您可以通过运行以下实验快速看到:

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插入。您已经在做一件事(在您的代码中(会有所作为。

最新更新