加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 协议缓冲区数组中浪费的字节数?

发布时间:2020-12-16 01:41:47 所属栏目:百科 来源:网络整理
导读:我有一个像这样的协议缓冲区设置: [ProtoContract]Foo{ [ProtoMember(1)] Bar[] Bars;} 单个Bar被编码为67字节的协议缓冲区.这听起来是正确的,因为我知道Bar几乎只是一个64字节的数组,然后有3个字节的开销用于长度前缀. 但是,当我使用20 Bars的数组编码Foo
我有一个像这样的协议缓冲区设置:

[ProtoContract]
Foo
{
    [ProtoMember(1)]
    Bar[] Bars;
}

单个Bar被编码为67字节的协议缓冲区.这听起来是正确的,因为我知道Bar几乎只是一个64字节的数组,然后有3个字节的开销用于长度前缀.

但是,当我使用20 Bars的数组编码Foo时,需要1362个字节. 20 * 67是1340,所以只有22个字节的开销用于编码数组!

为什么这会占用这么多空间?我能做些什么来减少它吗?

解决方法

这个开销很简单,它需要知道20个对象中每个对象的开始和结束位置.在没有破坏格式的情况下,我可以做任何不同的事情(即做一些违反规范的事情).

如果你真的想要血淋淋的细节:

数组或列表(如果我们排除“打包”,这里不适用)只是重复的子消息块.有两种布局可用于子消息;字符串和组.使用字符串,布局为:

[header][length][data]

其中header是wire-type和field-number的varint编码的mash(在这种情况下为字段1的十六进制08),length是varint编码的数据大小,data是子对象本身.对于小对象(数据小于128字节),这通常意味着每个对象有2个字节的开销,具体取决于:字段编号(15以上的字段占用更多空间),b:数据的大小.

对于一个组,布局是:

[header][data][footer]

其中header是wire-type和field-number的varint编码的mash(在这种情况下是字段1的十六进制0B),data是子对象,footer是另一个varint mash,用于指示对象的结尾(hex在这种情况下0C与字段1).

群体通常不那么受欢迎,但它们的优势在于,随着数据量的增长,它们不会产生任何开销.对于小的字段数(小于16),开销是每个对象2个字节.当然,您需要为大字段数支付双倍的费用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读