簡體   English   中英

使用JNI有效地將GPB序列化數據從Java傳遞到C ++

[英]Efficiently passing GPB serialized data from Java to C++ using JNI

這些天來,我正在尋找一種將復雜的數據結構從Java傳遞到本機(C ++)dll,反之亦然的方法。 在閱讀了許多有關JNI及其開銷的文章之后,我開始尋找一種有效的方法來在Java /本機端序列化數據並將其作為一個數據塊傳遞給另一端。 這樣,可以節省許多JNI調用。 目前,我使用Google協議緩沖區序列化許多復雜的類,並將此數據通過單個JNI調用傳遞給本機層。 看起來不錯。 例如,在Java端對4000個小類進行序列化,在本機端進行JNI調用和反序列化在i7上花費了約1.6ms。

通過調用GPB_GENERATED_CLASS在Java端進行序列化。 build.toByteArray()實際上每次調用都會創建一個新的字節數組。 之后,使用put()函數數組數據復制到直接ByteBuffer中。

Google協議緩沖區序列化器提供了另一個功能,該功能能夠將序列化的數據寫入OutputStream。

我的問題是:

  1. 有沒有一種方法可以將序列化的數據傳遞給JNI(本機),而無需在每次調用時復制和創建新對象?
  2. 有沒有一種方法可以一次分配ByteArrays或DirectByteBuffers,並使用它們將數據從Java傳遞到JNI,反之亦然(使用OutputStream?)?
  3. 任何其他可能會提高性能並節省垃圾收集操作的技巧都將受到歡迎。

謝謝

Google協議緩沖區(GPB)消息實現還提供了writeTo方法。

ByteArrayOutputStream與您要查找的內容非常接近,但是,每當您訪問內部字節數組時,它都會創建一個新副本,聽起來似乎並不像您要找的內容。 但是,如果創建自己的OutputStream實現(類似於ByteArrayOutputStream),則可以控制內部字節數組或DirectByteBuffer的生命周期。 這應該使您能夠提高性能並減少壽命短的對象。

writeTo

void writeTo(OutputStream output)

序列化消息並將其寫入輸出。 這只是writeTo(CodedOutputStream)的一個簡單包裝。 這不會刷新或關閉流。

注意:協議緩沖區不是自定界的。 因此,如果在消息后將更多數據寫入流,則必須以某種方式確保接收方的解析器不會將其解釋為協議消息的一部分。 例如,可以通過在數據之前寫入消息的大小,然后確保在接收端將輸入限制為該大小來完成此操作(例如,通過將InputStream包裝在限制輸入的內容中)。 或者,只需使用writeDelimitedTo(OutputStream)。

拋出:IOException拋出IOException

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM