[英]java: package jdk.incubator.foreign is not visible error in Java 15
[英]Java: Performance of ByteBuffer versus jdk.incubator.foreign (Panama) Foreign Memory methods (MemoryLayout/Segment)
我在业余时间自学数据库,试图通过实施一个从头开始来学习。
您必须实现的第一件事是底层数据格式和存储机制。
在 DB 中,有一个称为“Slotted Page”的结构,如下所示:
+-----------------------------------------------------------+
| +----------------------+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ |
| | HEADER | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | |
| +----------------------+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ |
| SLOT ARRAY |
| |
| |
| |
| +--------------------+ +----------------+ |
| | TUPLE #4 | | TUPLE #3 | |
| | | | | |
| +--------------------+ +----------------+ |
| +--------------------------+ +------------------+ |
| | TUPLE #2 | | TUPLE #1 | |
| | | | | |
| +--------------------------+ +------------------+ |
+-----------------------------------------------------------+
页面数据通过二进制序列化存储到文件中。 插槽是最简单的部分,其定义可能如下所示:
struct Slot {
uint32_t offset;
uint32_t length;
}
在 C++ 中,读/写的过程可能是std::memcpy
void write_to_buffer(char *buffer, Slot& slot) {
memcpy(buffer + slot.offset, &slot.length, sizeof(uint32_t));
memcpy(buffer + slot.offset + sizeof(uint32_t), &slot.length, sizeof(uint32_t));
}
void read_from_buffer(char *buffer, Slot& slot) {
memcpy(&slot.offset, buffer + slot.offset, sizeof(uint32_t));
memcpy(&slot.length, buffer + slot.offset + sizeof(uint32_t), sizeof(uint32_t));
}
在 Java 中,据我所知,您可以执行以下两种操作之一:
record Slot(int offset, int length) {
void write(ByteBuffer buffer) {
buffer.putInt(offset).putInt(length);
}
static Slot read(ByteBuffer buffer) {
return new Slot(buffer.getInt(), buffer.getInt());
}
}
record Slot(int offset, int length) {
public static MemoryLayout LAYOUT = MemoryLayout.structLayout(
ValueLayout.JAVA_INT.withName("offset"),
ValueLayout.JAVA_INT.withName("length"));
public static TupleSlot from(MemorySegment memory) {
return new TupleSlot(
memory.get(ValueLayout.JAVA_INT, 0),
memory.get(ValueLayout.JAVA_INT, Integer.BYTES));
}
public void to(MemorySegment memory) {
memory.set(ValueLayout.JAVA_INT, 0, offset);
memory.set(ValueLayout.JAVA_INT, Integer.BYTES, length);
}
}
这些之间的性能差异是什么?
如果可以忽略不计,我更喜欢 ByteBuffer API。
在panama-dev
邮件列表中回复 Paul Sandoz 的回复:
嗨,加文,
与 ByteBuffer 相比,使用 MemorySegment 将使您对描述(布局)和管理(释放和池化)有更多的控制。 此外,如果这是一个问题,您也不会受到 ByteBuffer 大小限制的限制。 使用 MemorySegment 在性能方面应该与 ByteBuffer 一样好或更好。
在许多方面 MemorySegment 是更好的 API 与原生 memory 交互。 ByteBuffer 是在 Java 1.4 中与 NIO 一起引入的,并且考虑到了今天不太相关的其他设计约束(例如内部可变索引)。
保罗。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.