在 Map 中存储字节值是否有意义,或者它仍将使用 4 个字节?

Does it make sense to store byte values in Map or it will still use 4 bytes?

在 Java 内存中,byte 或 int 之间没有区别 - 两者都将表示为 4 个字节。

Chronicle Map 是否存在差异,即 Chronicle Map 将字节值存储为 8 位还是仍然使用 32 位?

同样的问题如果字节是一个对象属性。

我想我知道回应。至少在 2.3.8 版本中,堆外值将为一个字节 1 个字节(在 SerializationBuilder class 中完成的工作)。

在原始地图实现中(fastutil、koloboke、gs、hppc)byte 值作为单独的 byte[] 数组实现,因此它们实际上只占用 1 个字节。如果 byte 是另一个堆上 Java 对象(这是一个 Map 值)的字段,实际上,对象大小被四舍五入到 8 字节边界,所以单个 byte 字段可以 "take" 8 个字节。但更多时候,它 "takes" 0 字节,因为该字段被放置在已经存在的对齐孔中。

对于 Chronicle Map,值的大小可以是 1 个字节。 (甚至 0 字节,这就是 ChronicleSet 当前的实现方式——具有 0 字节虚拟值的 ChronicleMap。)对于所有 Chronicle Map 版本 (2, 3) 都是如此。


编辑 -- 回复评论。

如果你有一个固定大小的结构 e。 G。 6 字节字段,最简单有效的方法 - 使用数据值生成机制:

interface MyValue {
    byte getA(); void setA(byte a);
    byte getB(); void setB(byte b);
    byte getC(); void setC(byte c);
    byte getD(); void setD(byte d);
    byte getE(); void setE(byte e);
    byte getF(); void setF(byte f);
}

map = ChronicleMapBuilder.of(Key.class, MyValue.class).entries(1000).create();

// Chronicle Map 2 syntax
MyValue value = DataValueClasses.newDirectReference(MyValue.class);
try (Closeable handle = map.getUsingLocked(key, value)) {
    // access the value here
    System.out.println(value);
}

// Chronicle Map 3 syntax
try (ExternalMapQueryContext<Key, MyValue, ?> q = map.queryContext(key)) {
    // if not sure the key is present in the map, check q.entry() != null
    MyValue value = q.entry().value().get();
    // access the value here
    System.out.println(value);
}

每个值正好需要 6 个字节。