我有一个 byte[],其中包含序列化的 C++ 数据类型(因此它具有标准 Java 序列化类无法理解的奇怪格式)。我创建了自己的反序列化器,它将标志与类型匹配并将其转换为适当的对象,如下所示(输入可能类似于 int64,值为 4 [3, 0, 0, 0, 0, 0, 0, 0, 4], 3 是 int64 的标志)
private final ByteBuffer byteWrapper;
// member ByteBuffer which is allocated in the ctor
ctor { byteWrapper = ByteBuffer.allocateDirect(8); }
// somewhere in the parse function, this case matches an int64
case 3:
{
return byteWrapper.wrap(ios.getBytes(8)).getLong();
}
其中ios包含完整的序列化数据,以便于阅读。现在这工作正常,但是高吞吐量对于这段代码非常重要,而且我不是一个普通的 Java 程序员,所以我只是想知道是否有人对加快这个过程有任何建议,或者通过重新设计我的内容已经拥有或完全使用不同的类/函数或其他什么?内存不是问题,我只是对速度感兴趣
最佳答案
不要将数据复制到新的缓冲区对象中。直接从ios缓冲区读取。
byte type = ios.get();
switch (type) {
case 3:
return ios.getLong();
}
ByteBuffer中的所有getter都会根据数据类型的长度增加位置。 get()将位置增加1,getLong()增加8,getFloat()增加4...可以直接使用ios.getLong()。假设这些值被一个接一个地写入,新位置将指向下一个类型字节。所以你可以直接调用ios.get()来获取下一个类型。
编辑:
如果ios是InputStream则可以使用DataInputStream来读取。它还支持各种数据类型。
DataInputStream input = new DataInputStream(ios);
byte type = input.readByte();
switch (type) {
case 3:
return input.readLong();
}
在 Java 中,本质上有两个包可以提供您正在寻找的功能。 java.io 和 java.nio。 java.io 包含 Streams,而 java.nio 包含 Buffers。 java.nio 速度更快,因为它使用非常低级的内存操作。如果你追求速度,你应该使用它。这也意味着如果可能的话,您应该将 ios 的类型更改为 ByteBuffer,然后使用我的第一种方法。
关于Java:非常有效地将字节流转换为对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36352967/