这些天我正在寻找一种方法将复杂的数据结构从Java传递到本机(C ++)DLL,反之亦然。在阅读了很多关于JNI的文章及其开销之后,我开始寻找一种有效的方法来序列化Java / native端的数据,并将其作为一大块数据传递给另一端。这样,可以保存许多JNI调用。 目前,我使用Google Protocol Buffers序列化许多复杂类,并通过单个JNI调用将此数据传递给本机层。 看起来不错。例如,Java端的4000个小类的序列化,本机端的JNI调用和反序列化在i7上需要大约1.6ms。
java端的序列化是通过调用GPB_GENERATED_CLASS。 build.toByteArray()来完成的,它会在每次调用时创建一个新的字节数组。 之后,使用 put()函数将数组数据复制到直接ByteBuffer中。
Google协议缓冲区序列化程序提供了另一个能够将序列化数据写入OutputStream的函数。
我的问题是:
谢谢
答案 0 :(得分:2)
Google协议缓冲区(GPB)邮件实施还提供了writeTo
方法。
ByteArrayOutputStream
非常接近您要查找的内容,但是,无论何时访问内部字节数组,它都会创建一个新副本,这听起来不像您要查找的内容。但是,如果您创建自己的OutputStream实现(类似于ByteArrayOutputStream),则可以控制内部字节数组的生命周期,或DirectByteBuffer
。这应该允许您提高性能并减少短期对象。
writeTo
void writeTo(OutputStream output)
序列化消息并将其写入输出。这只是一件小事 writeTo(CodedOutputStream)的包装器。这不会冲洗或 关闭溪流。
注意:协议缓冲区不是自定义的。因此,如果你 在消息之后将更多数据写入流,你必须以某种方式 确保接收端的解析器不会将其解释为 成为协议消息的一部分。这可以通过例如完成。通过写作 数据之前的消息大小,然后确保限制 在接收端输入该大小(例如通过包装 InputStream中的一个限制输入)。或者,只需使用 writeDelimitedTo(OutputStream中)。
抛出: IOException抛出IOException