Protobuf 二进制格式的设计:性能和 varint
Design of the Protobuf binary format: performance and varint
我需要设计一种二进制格式来保存来自科学应用程序的数据。此数据必须以二进制格式编码,任何其他应用程序都无法轻松读取(这是我们的一些客户的要求)。因此,我们决定构建自己的二进制格式、编码器和解码器。
我们从许多二进制格式中得到了一些启发,包括 protobuf。令我困惑的一件事是 protobuf 对嵌入消息的长度进行编码的方式。根据 https://developers.google.com/protocol-buffers/docs/encoding,嵌入消息的大小在其最开始被编码为 varint。
但是在我们对嵌入消息进行编码之前,我们还不知道它的大小(例如,考虑包含许多编码为 varint 的整数的嵌入消息)。因此,我们需要在将消息写入磁盘之前对消息进行完整编码,以便我们知道其大小。
想象一下,这条消息是巨大的。因此,很难以有效的方式对其进行编码。我们可以将这个大小编码为一个完整的 int 并在写入嵌入消息后返回文件的这一部分,但是我们失去了 varints 的好处 属性 :如果你有一个 32,你不需要指定位或 64 位整数。所以回到 Google 使用 varint 的实现:
是否有我遗漏的实现技巧,或者此方案对于大消息可能效率低下?
是的,执行此操作的正确方法是先在缓冲区的后面写入消息,然后在前面加上大小。通过适当的缓冲区管理,您可以反向写入消息。
就是说,既然可以使用 protobuf,为什么还要编写自己的消息格式?直接使用 Protobuf 并加密文件格式会更好。这对你来说很容易使用,但对其他应用程序来说仍然很难阅读。
我需要设计一种二进制格式来保存来自科学应用程序的数据。此数据必须以二进制格式编码,任何其他应用程序都无法轻松读取(这是我们的一些客户的要求)。因此,我们决定构建自己的二进制格式、编码器和解码器。
我们从许多二进制格式中得到了一些启发,包括 protobuf。令我困惑的一件事是 protobuf 对嵌入消息的长度进行编码的方式。根据 https://developers.google.com/protocol-buffers/docs/encoding,嵌入消息的大小在其最开始被编码为 varint。 但是在我们对嵌入消息进行编码之前,我们还不知道它的大小(例如,考虑包含许多编码为 varint 的整数的嵌入消息)。因此,我们需要在将消息写入磁盘之前对消息进行完整编码,以便我们知道其大小。 想象一下,这条消息是巨大的。因此,很难以有效的方式对其进行编码。我们可以将这个大小编码为一个完整的 int 并在写入嵌入消息后返回文件的这一部分,但是我们失去了 varints 的好处 属性 :如果你有一个 32,你不需要指定位或 64 位整数。所以回到 Google 使用 varint 的实现:
是否有我遗漏的实现技巧,或者此方案对于大消息可能效率低下?
是的,执行此操作的正确方法是先在缓冲区的后面写入消息,然后在前面加上大小。通过适当的缓冲区管理,您可以反向写入消息。
就是说,既然可以使用 protobuf,为什么还要编写自己的消息格式?直接使用 Protobuf 并加密文件格式会更好。这对你来说很容易使用,但对其他应用程序来说仍然很难阅读。