gpt4 book ai didi

具有所有键的单字节 [] 数组的 Java hashmap

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:12:32 26 4
gpt4 key购买 nike

我有一个相当大的数据集,包含 2.3GB 的数据,分布在 1.6 亿字节 [] 数组中,平均数据长度为 15 字节。每个 byte[] 键的值只是一个 int,因此 hashmap 的近一半(超过 6GB)的内存使用量由每个字节数组的 16 字节开销组成

开销 = 8 字节 header + 4 字节长度,由 VM 四舍五入为 16 字节。

所以我的开销是 2.5GB。

有没有人知道将其(可变长度)byte[] 键存储在一个大字节数组中的 hashmap 实现,这样就没有开销(除了 1 字节长度字段)?

我宁愿不使用内存数据库,因为与我正在使用的普通 Trove TObjectIntHashMap 相比,它们通常有性能开销,而且我更看重 cpu 周期,而不是内存使用。

提前致谢

最佳答案

由于如今大多数个人电脑都有 16GB,而服务器通常有 32-128GB 或更多,因此一定程度的簿记开销是否真的存在问题?

如果我们考虑替代方案:将字节数据连接到一个大数组中——我们应该考虑单个值必须是什么样子,才能引用更大数组的一部分。

通常你会从:

开始
public class ByteSlice {
protected byte[] array;
protected int offset;
protected int len;
}

但是,这是 8 个字节 + 指针的大小(也许只有 4 个字节?)+ JVM 对象 header (在 64 位 JVM 上为 12 个字节)。所以可能总共 24 个字节。

如果我们尝试使这个单一用途和极简主义,我们仍然需要 4 个字节作为偏移量。

public class DedicatedByteSlice {
protected int offset;
protected byte len;

protected static byte[] getArray() {/*somebody else knows about the array*/}
}

这仍然是 5 个字节(可能填充到 8 个)+ JVM 对象头。可能仍然总共 20 个字节。

似乎使用偏移量和长度取消引用的成本,并有一个对象来跟踪它,并不比直接存储小数组的成本低很多。

另一种理论上的可能性——解构 Map Key,使其不是对象

可以设想解构“长度和偏移量”数据,使其不再存在于对象中。然后它作为一组标量参数传递,例如 (length, offset) 并且——在 HashMap 实现中——将通过单独组件的数组存储(例如,而不是单个 Object[] keyArray)。

但是我认为任何库都不太可能为您的(非常特殊的)用例提供现有的 hashmap 实现。

如果您谈论的是,那可能毫无意义,因为 Java 不提供多个返回值或方法 OUT 参数;如果不将解构数据“装箱”回对象,这使得通信变得不切实际。由于您在这里具体询问映射键,并且这些键作为参数传递但不需要返回,因此理论上可以考虑这种方法。

[扩展]即使考虑到这一点,它也变得很棘手——对于您的用例, map API 可能必须针对人口与查找变得不对称,因为人口必须按 (offset, len) 来定义键;而实际查找可能仍然是通过具体的 byte[] 数组。

OTOH:即使是相当老旧的笔记本电脑现在也有 16GB。你写这篇文章的时间(4-10 次维护)应该比额外 RAM 的小成本更有值(value)。

关于具有所有键的单字节 [] 数组的 Java hashmap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41841786/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com