java - 使用 JNI 将 GPB 序列化数据从 Java 高效传递到 C++

标签 java java-native-interface protocol-buffers outputstream bytebuffer

这些天我正在寻找一种将复杂数据结构从 Java 传递到 native (C++) dll 的方法,反之亦然。在阅读了许多有关 JNI 及其开销的文章后,我开始寻找一种有效的方法来序列化 Java/ native 端的数据并将其作为一个数据 block 传递到另一端。这样,可以节省许多 JNI 调用。 目前,我使用 Google Protocol Buffers 来序列化许多复杂的类,并通过单个 JNI 调用将此数据传递到 native 层。 看上去不错。例如,Java 端的 4000 个小类的序列化、 native 端的 JNI 调用和反序列化在 i7 上大约需要 1.6ms。

Java 端的序列化是通过调用 GPB_GENERATED_CLASS 来完成的。build.toByteArray() 实际上在每次调用时都会创建一个新的字节数组。 之后,使用 put() 函数将数组数据复制到直接 ByteBuffer 中。

Google Protocol Buffer 序列化器提供了另一个函数,可以将序列化数据写入OutputStream。

我的问题是:

  1. 有没有办法将序列化数据传递到 JNI( native ),而无需在每次调用时复制和创建新对象?
  2. 有没有办法一次性分配 ByteArrays 或 DirectByteBuffers 并使用它们将数据从 Java 传递到 JNI,反之亦然(使用 OutputStream?)?
  3. 任何其他可能提高性能并节省垃圾收集操作的提示都将受到欢迎。

谢谢

最佳答案

Google Protocol Buffers(GPB) 消息实现还提供 writeTo方法。

ByteArrayOutputStream与您正在寻找的内容非常接近,但是,每当您访问内部字节数组时,它都会创建一个新副本,这听起来不像您正在寻找的内容。但是,如果您创建自己的 OutputStream 实现,类似于 ByteArrayOutputStream,您可以控制内部字节数组的生命周期,或 DirectByteBuffer 。这应该可以让您提高性能并减少短命对象。

writeTo

void writeTo(OutputStream output)

Serializes the message and writes it to output. This is just a trivial wrapper around writeTo(CodedOutputStream). This does not flush or close the stream.

NOTE: Protocol Buffers are not self-delimiting. Therefore, if you write any more data to the stream after the message, you must somehow ensure that the parser on the receiving end does not interpret this as being part of the protocol message. This can be done e.g. by writing the size of the message before the data, then making sure to limit the input to that size on the receiving end (e.g. by wrapping the InputStream in one which limits the input). Alternatively, just use writeDelimitedTo(OutputStream).

抛出: IOException 抛出 IOException

关于java - 使用 JNI 将 GPB 序列化数据从 Java 高效传递到 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22062124/

相关文章:

java - jni 中接口(interface)的 isinstance

android - 无法使用 Superpowered 库为 arm64-v8a 创建 so 文件

java - Netbeans(用于 c/c++ 的 MinGW 编译器)可以调用任意 C/C++ DLL(在 VS'05 中编译)吗?

c# - 反序列化 Protocol Buffer c++中的字符串数组

python-3.x - 在Docker文件中设置mysql-connector-python

java - Jsch - 每个 session 多个 channel

java - 关于TCP连接强制关闭的问题

java - 由 : java. lang.NullPointerException 引起:尝试调用虚拟方法 'java.lang.String com.facebook.Profile.getFirstName()'

java - 快速排序。线程中出现异常 "main"java.lang.StackOverflowError

parsing - protobuf 文本格式解析映射