Google协议缓冲区的典型内存空间使用情况是多少?

时间:2012-11-13 19:38:19

标签: protocol-buffers

我正在开发一种小型设备,它具有相当大的配置参数(~100 KB),这些参数是从PC软件生成的。过去,我们将参数存储在二进制文件中,并将它们加载到数据结构中。维护有点烦人(不同的语言,确保结构中的字段顺序匹配,不同的版本等),所以我们正在考虑使用Google协议缓冲区。

从小型设备的角度来看,我担心存储序列化协议缓冲区所需的内存空间。我在C工作,所以我下载了protobuf-embedded-c并开始研究一个例子。我对它计算的缓冲区的最大大小感到有些惊讶。例如,接下来是空缓冲区的大小,然后是包含命名类型的单个变量的缓冲区:

#define MAX_M_Empty_SIZE 2
#define MAX_M_double_SIZE 12
#define MAX_M_float_SIZE 8
#define MAX_M_int32_SIZE 14
#define MAX_M_int64_SIZE 14
#define MAX_M_uint32_SIZE 9
#define MAX_M_uint64_SIZE 14
#define MAX_M_sint32_SIZE 9
#define MAX_M_sint64_SIZE 14
#define MAX_M_fixed32_SIZE 8
#define MAX_M_fixed64_SIZE 12
#define MAX_M_sfixed32_SIZE 8
#define MAX_M_sfixed64_SIZE 12
#define MAX_M_bool_SIZE 5

每次我在结构中添加'int32'时,最大大小增加了14个字节。我知道这包括关键,可能是Variant编码的最坏情况,但我可以期待什么呢?较大的消息比较小的消息更有效,还是更依赖于编码值?

总之,我只是想了解一下协议缓冲区的内存空间使用情况。我讨厌使用易用性来大量增加存储配置数据所需的内存空间。谢谢!

2 个答案:

答案 0 :(得分:2)

int32被写为 varint ,这意味着对于正值,它所占用的空间取决于幅度。小正值可以是单字节;较大的正值可能需要更多。负值会占用更多空间 - 特别是,它需要与非常大的 64位数字相同。 “varint”是7位加上延续;所以负数(或大的正数)可以占用10个字节。为避免这种情况,如果您知道自己的值可能为负值,则可以使用sint32 / sint64 - 这会使用 zig-zag 编码(然后 varint ) - 基本上使小幅度值比大幅度值占用更少的空间(无论符号如何)。

如果您需要针对最坏情况进行优化,那么可以考虑使用fixed32 / fixed64代替;这保证了恰好4或8个字节。

要点:

  • 总是(或几乎总是)正面,通常是小到中等大小:int32 / int64
  • 正面或负面,通常为中小幅度:sint32 / sint64
  • 大值,或需要保证大小:fixed32 / fixed64

还有其他几个;完整的详细信息位于language guide

(在上面的所有情况下,你还需要包含标题,但通常是1或2个字节)

答案 1 :(得分:1)

Nanopb可以使用非常小的内存空间,它也可以直接与文件串行化,以避免需要内存缓冲区: http://koti.kapsi.fi/jpa/nanopb/