在 protobuf 消息或嵌套消息中最好有很多字段吗?
Is it best to have many field in protobuf message or nested messages?
我试图在网上找到一些建议,但找不到任何相关内容。
假设我正在创建一个包含很多字段 (50+) 的协议缓冲区消息。最好将所有字段保持在同一级别还是将它们组织在子消息中?对性能有任何影响吗?
示例:
message myMessage{
string field1 = 1;
string field2 = 2;
....
string fieldn = n;
}
对
message myMessage{
SubMessage1 groupedfieldsbasedonsomebusinesslogic1 = 1;
SubMessage2 groupedfieldsbasedonsomebusinesslogic2 = 2;
message SubMessage1{
string field1 = 1;
string field2 = 2;
...
string fieldx = x;
}
message SubMessage2{
string fieldxplus1 = x+1;
...
string fieldn = n;
}
}
我在这里没有过多考虑可读性,因为在反序列化为平面数据或嵌套数据时有利有弊。我的问题实际上是关注技术影响。
没有"best" - 一切都是上下文相关的,只有你拥有大部分上下文。
但是!关于性能的一些小想法:
- 嵌套方法需要更多 object;通常这很好,除非你的体积很大
- 嵌套方法可能更容易理解 object 模型和数据某些部分之间的关系
- 平面方法需要更大的字段数;字段编号 1-15 占用一个字节 header;字段编号 16-2047 需要 2 个字节 header(依此类推);实际上,几个字段的这个额外字节不太可能对您造成太大伤害,并且被替代(嵌套)方法的开销所抵消:
- 嵌套方法需要每个 sub-object 一个 length-prefix 或一个 start/end 令牌(协议中的 "group");就额外尺寸而言,这并不多,但是:
- length-prefixe 要求序列化程序提前知道长度,这意味着 double-processing("compute length" 扫描),或者缓冲;在大多数情况下,这不是一个大问题,但对于非常大的 sub-graphs
来说可能会有问题
- start/end 令牌是 google 一直试图杀死的东西,并且在所有库中都没有得到很好的支持(并且 IIRC 它在 "proto3" 模式中不存在);不过,我仍然很喜欢它,在某些情况下 :) protobuf-net(来自标签)支持将任意 sub-data 编码为组的能力,但如果你需要 x-plat 可能会很尴尬后来
在所有这些事情中,如果是我,我会关注的是第二个。
也许从一些看起来可用的东西开始,然后测量它的实际数据量;它的表现是否令人满意?
我试图在网上找到一些建议,但找不到任何相关内容。
假设我正在创建一个包含很多字段 (50+) 的协议缓冲区消息。最好将所有字段保持在同一级别还是将它们组织在子消息中?对性能有任何影响吗?
示例:
message myMessage{
string field1 = 1;
string field2 = 2;
....
string fieldn = n;
}
对
message myMessage{
SubMessage1 groupedfieldsbasedonsomebusinesslogic1 = 1;
SubMessage2 groupedfieldsbasedonsomebusinesslogic2 = 2;
message SubMessage1{
string field1 = 1;
string field2 = 2;
...
string fieldx = x;
}
message SubMessage2{
string fieldxplus1 = x+1;
...
string fieldn = n;
}
}
我在这里没有过多考虑可读性,因为在反序列化为平面数据或嵌套数据时有利有弊。我的问题实际上是关注技术影响。
没有"best" - 一切都是上下文相关的,只有你拥有大部分上下文。
但是!关于性能的一些小想法:
- 嵌套方法需要更多 object;通常这很好,除非你的体积很大
- 嵌套方法可能更容易理解 object 模型和数据某些部分之间的关系
- 平面方法需要更大的字段数;字段编号 1-15 占用一个字节 header;字段编号 16-2047 需要 2 个字节 header(依此类推);实际上,几个字段的这个额外字节不太可能对您造成太大伤害,并且被替代(嵌套)方法的开销所抵消:
- 嵌套方法需要每个 sub-object 一个 length-prefix 或一个 start/end 令牌(协议中的 "group");就额外尺寸而言,这并不多,但是:
- length-prefixe 要求序列化程序提前知道长度,这意味着 double-processing("compute length" 扫描),或者缓冲;在大多数情况下,这不是一个大问题,但对于非常大的 sub-graphs 来说可能会有问题
- start/end 令牌是 google 一直试图杀死的东西,并且在所有库中都没有得到很好的支持(并且 IIRC 它在 "proto3" 模式中不存在);不过,我仍然很喜欢它,在某些情况下 :) protobuf-net(来自标签)支持将任意 sub-data 编码为组的能力,但如果你需要 x-plat 可能会很尴尬后来
在所有这些事情中,如果是我,我会关注的是第二个。
也许从一些看起来可用的东西开始,然后测量它的实际数据量;它的表现是否令人满意?