2017-06-06 26 views
0

我需要設計一個二進制格式來保存來自科學應用程序的數據。這些數據必須以二進制格式進行編碼,這是任何其他應用程序都無法輕易讀取的(這是我們某些客戶的要求)。因此,我們決定構建自己的二進制格式,編碼器和解碼器。Protobuf二進制格式的設計:性能和varint

我們從許多二進制格式中得到了一些啓示,包括protobuf。讓我困惑的一件事是protobuf對嵌入消息的長度進行編碼的方式。根據https://developers.google.com/protocol-buffers/docs/encoding,嵌入式消息的大小在其最初被編碼爲varint。 但是,在我們編碼一個嵌入式消息之前,我們還不知道它的大小(想想嵌入式消息包含許多編碼爲varint的整數)。因此,我們需要完全編碼消息,然後再將其寫入磁盤,以便知道其大小。想象一下,這個消息是巨大的。因此,以有效的方式對其進行編碼是非常困難的。我們可以將這個大小編碼爲一個完整的int值,並且一旦嵌入的消息被寫入,就回到文件的這個部分,但是我們失去了varints的好處:你不需要指定是否有32位或者64位整數。因此,回到谷歌的實施使用varint:

是否有我缺少的實現技巧,或者這種方案可能是低效的大消息?

+0

對於科學數據和大文件,請看HDF5。如果數據量很大,它的性能通常比protobuf更好。 – jpa

回答

0

是的,正確的做法是首先在緩衝區後面寫入消息,然後預先設置大小。通過適當的緩衝區管理,您可以反向寫入消息。

這就是說,爲什麼寫你自己的消息格式,當你只能使用protobuf?直接使用Protobuf並加密文件格式會更好。這對您來說很容易使用,而其他應用程序仍然難以閱讀。

+0

爲什麼我不想使用protobuf有很多原因。最主要的是我想要一些動態的東西,在保存的文件中使用鍵和類型,以及BSON和MessagePack的工作方式。另一個原因是我將存儲uint16的數組(對於16位深度的灰度圖像)。 protobuf沒有總是需要2個字節的uint16類型這一事實沒有幫助。 – InsideLoop

+0

那我能問你爲什麼發佈一個關於Protobuf的問題嗎?看起來不合適,因爲你需要一種非常不同的電線格式。 –

+0

因爲我想竊取來自不同文件格式的最佳創意。這就是我想理解他們背後的理由,他們的優點和缺點的原因。 – InsideLoop