Java:非常有效地将字节流转换为对象

标签 java performance bytebuffer

我有一个 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/

相关文章:

java - 使用 Java 打开位于另一个存档文件中的存档文件

java - lint 检查未使用的方法(命令行)

javascript - 优化大型 jquery POST 的最佳方法是什么?

mysql - 将所有对网站的请求记录在数据库中

java - 在 Java 中连接两个 ByteBuffer

java - 大端字节缓冲区中的字节顺序

java - JVM 如何实现可变参数?

java - 在 Java 中更新 Mock 对象

c++ - 从 istringstream 读取比 ifstream 慢

java - 如何将 ArrayList<Vector3f> 转换为 ByteBuffer?