gpt4 book ai didi

c++ - 编码、数据类型和打包的重复字段

转载 作者:行者123 更新时间:2023-11-30 03:03:49 27 4
gpt4 key购买 nike

我有一些关于打包字段和存储/序列化的问题带有 Protocol Buffer 的数据。我基本上想做的是将 4MB 的数据存储到一个文件中。

我拥有的数据(在我们的嵌入式系统中)以 uint8_t(一个字节)的形式接收,我想尽可能高效地存储这些数据。

我一直在测试各种 protobuf 设置(四种);

repeated uint32_t datastruct = 1;
repeated uint32_t datastruct = 1 [packed = true]

两个变体都被一对一分配(将 uint8 赋值给 uint32),并且两个变体都用 4 个值移位到一个 uint32_t 中。

令我惊讶的是,存储的文件比原始文件大得多数据。 (当然,我将 uint8 放入 uint32 的示例是预期的......)对于 4MB 数据,我能达到的最好结果是 5.2MB,这真的不是那么好。

我是不是误解了一些重要的东西?我确实意识到 protobuf 向数据包添加了信息,但是 25%恕我直言,增加太多了。

同样使用 GzipOutputStream 会增加文件的大小而不是减少它。

如有任何提示,我们将不胜感激!

感谢您的宝贵时间。

最佳答案

这个答案是基于你在 .proto 术语中使用 uint32 的假设:

packed 在这里是一件好事(删除每个值的 header );但是,通过将单个 uint8 打包到 uint32 中,您将遇到“varint”编码的一个方面——具体来说,如果设置了字节的最高有效位,它将占用 2 个字节(varint 每个字节使用 7 位数据,一位作为 continuation)。因此,我建议切换到 bytes 类型,它代表任意字节 block ,并且“按原样”编码,没有任何 varint 或类似的。它不会被重复/打包 - 只是:

[required|optional] bytes data = 1;

另一种选择是使用 fixed32(重复和压缩),并为每个值放置(通过移位)4 个字节,但是当您完成后,您也可以转到 bytes 有更明显的1:1映射。

重新压缩; gzip 在没有许多重复 block 的情况下增加任意二进制文件的大小并不少见。相比之下,如果您的 protobuf 文档包含字符串,则大小通常会缩小,因为 gzip 可以发现重复的 block 。

关于c++ - 编码、数据类型和打包的重复字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9160646/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com