Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 协议缓冲区阵列中浪费的字节?_C#_Protocol Buffers_Protobuf Net - Fatal编程技术网

C# 协议缓冲区阵列中浪费的字节?

C# 协议缓冲区阵列中浪费的字节?,c#,protocol-buffers,protobuf-net,C#,Protocol Buffers,Protobuf Net,我有如下协议缓冲区设置: [ProtoContract] Foo { [ProtoMember(1)] Bar[] Bars; } 单个条编码到67字节的协议缓冲区。这听起来是对的,因为我知道一个条几乎就是一个64字节的数组,然后长度前缀会有3个字节的开销 然而,当我用一个20条的数组编码一个Foo时,它需要1362字节。20*67是1340,因此仅编码一个数组就有22字节的开销 为什么这会占用这么多空间?我能做些什么来减少它吗?默认情况下,数组实际上不是作为数组传递的,而是作

我有如下协议缓冲区设置:

[ProtoContract]
Foo
{
    [ProtoMember(1)]
    Bar[] Bars;
}
单个条编码到67字节的协议缓冲区。这听起来是对的,因为我知道一个条几乎就是一个64字节的数组,然后长度前缀会有3个字节的开销

然而,当我用一个20条的数组编码一个Foo时,它需要1362字节。20*67是1340,因此仅编码一个数组就有22字节的开销


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

默认情况下,数组实际上不是作为数组传递的,而是作为重复成员传递的,这会增加一些开销

所以我猜每个重复的数组元素实际上有1字节的开销,加上上面额外的2字节开销

使用“压缩”数组可能会损失开销。protobuf net支持这一点:


二进制格式的文档在这里:

这个开销只是它需要知道20个对象的开始和结束位置的信息。在这里,如果不打破格式(即,做一些与规范相反的事情),我无法做任何不同的事情

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

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

[header][length][data]
[header][data][footer]
其中,
header
是导线类型和字段号(在本例中为字段1的十六进制08)的可变编码mash,
length
数据的可变编码大小,数据是子对象本身。对于小对象(
data
小于128字节),这通常意味着每个对象的开销为2字节,具体取决于a:字段编号(大于15的字段占用更多空间)和b:数据大小

对于组,布局为:

[header][length][data]
[header][data][footer]
其中,
header
是导线类型和字段号的变量编码mash(在本例中为字段1的十六进制0B),
data
是子对象,
footer
是另一个变量mash,用于指示对象的结束(在本例中为字段1的十六进制0C)


组通常不太受欢迎,但它们的优势是,随着
数据的增长,它们不会产生任何开销。对于较小的字段号(小于16),开销也是每个对象2字节。当然,如果字段数较大,您需要支付双倍的费用。

而Foo本身是免费的吗?它也应该占用一些空间?它应该占用一些空间,但是22字节是一个很大的空间!1340之上的22字节并不是“那么多”,当然也不适合序列化。继续你的生活吧。我正在发送包含512个这些东西的协议缓冲区,每秒4到5个。这浪费了大量的带宽奇怪的是,在数组中使用压缩会触发一个异常“wire type:String不支持压缩缓冲区”。这很奇怪,因为酒吧不是一根弦@马丁-就protobuf规范而言:是的。这只是一个特定布局的名称-它并不意味着一个文本字符串。对象有两种可能的格式;字符串和组。Packed确实消除了头的开销,但只适用于非常基本的类型,如整数和浮点;不要反对。谢谢马克,我怀疑这可能是我遇到的协议中的一个令人讨厌的案例。