【问题标题】:Memory efficient map for byte array values字节数组值的内存高效映射
【发布时间】:2018-07-07 19:28:25
【问题描述】:

我正在尝试将大量数据加载到HashMap。目前我正在尝试推送 2000 万个条目。将这么多条目加载到此映射中时,我注意到考虑到我加载到此映射中的所有内容都是字节数组(我从 500mb 文件生成此数据,每个字节数组平均具有大小5 个,最多 11 个):

Map<Key, byte[]> result = new HashMap<>(entryCount, 1);
for (int i = 0; i < entryCount; i++) {
    do {
        // Read data from file, store it into result and increment count.
    } while (count < MAX_COUNT);   
}

还有Key 类:

public final class Key {

    private final byte[] value;

    Key(byte[] value) {
        this.value = value;
    }

    // equals, hashCode, toString
}

使用jProfiler 查找消耗这么多内存的内容,我注意到HashMap$Node 是图表顶部的类之一:

我很好奇这种确切类型的数据是否有更高效的 Map 实现?

【问题讨论】:

  • 您正在使用 26 meg 来存储 20 meg...Map 中是否有 ~100k 数组?
  • @ElliottFrisch 我存储了 2000 万个数组。我想知道是否有任何地图实现不为每个地图元素创建Node。对于我存储的这种特定类型的数据,也许有专门的地图实现。
  • Key有一个实例变量byte[] valueresult 映射的值类型也是byte[]。您是否将键 k 它的值放在地图中:result.put(k, k.getValue())?这将是多余的。该映射是不必要的,因为您需要知道键 k 才能从映射中获取值:result.get(k)。但是如果你有密钥k,那么你就有了它的值:k.getValue()。那么地图就不需要了。
  • @LuCio key 和我放在地图中的值完全不相关。密钥实际上是一个md5 哈希。而该值由从文件中读取的字节组成。

标签: java dictionary hashmap


【解决方案1】:

您可以使用特定类型的映射,如fastutil或trove等。例如,您可以使用满足您要求的fastutil中的Object2ByteArrayMap。

The fastuil api

【讨论】:

  • Object2ByteArrayMap 仅在内部使用字节数组,并且只允许每个键存储 1 个字节(不是数组)。还看了javadoc,看来这个数据结构是为少量条目构建的。
  • @Edd 是的,你是对的。你试过Object2ObjectMap吗?或者您可以自定义自己的地图。
  • 是的,我做到了。它有几千个条目,所以我放弃了这个想法。
猜你喜欢
  • 2014-01-25
  • 2019-09-21
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 2011-04-30
  • 1970-01-01
  • 2014-09-21
  • 1970-01-01
相关资源
最近更新 更多