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

时间:2016-04-01 09:42:43

标签: 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程序员,所以我只是想知道是否有人有任何关于加快这个过程的建议,无论是通过改造我所拥有的或完全使用不同的类/功能或任何东西?记忆不是问题,我只对速度感兴趣

1 个答案:

答案 0 :(得分:1)

不要将数据复制到新的缓冲区对象中。直接从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,然后使用我的第一种方法。