我有一个像这样的消息定义:
message Command{
oneof type{
Point point = 1;
Rotate rotate = 2;
Move move = 3;
... //about 100 messages
}
}
然后protoc生成SerializeWithCachedSizes函数:
void Command::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// @@protoc_insertion_point(serialize_start:coopshare.proto.Command)
::google::protobuf::uint32 cached_has_bits = 0;
(void) cached_has_bits;
// .coopshare.proto.Point point = 1;
if (has_point()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
1, *type_.point_, output);
}
// .coopshare.proto.Rotate rotate = 2;
if (has_rotate()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
2, *type_.rotate_, output);
}
// .coopshare.proto.Move move = 3;
if (has_move()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
3, *type_.move_, output);
}
“oneof”消息将特定类型保存在_oneof_case_中。我认为使用switch-case更有效率。
但为什么protobuf仍会生成这样的代码?
答案 0 :(得分:1)
Oneofs内部处理类似于可选字段。事实上,descriptor.proto将它们表示为一组可选字段,只有一个额外的oneof_index
来表示它们属于一起。这是一个合理的选择,因为它允许oneofs在添加任何特殊支持之前立即与许多库一起使用。
我假设C ++代码生成器对可选字段和oneofs使用相同的结构。
switch-case有可能生成更高效的代码,在这种情况下,建议将其作为protobuf项目的改进是有用的。但是,正如JorgeBellón在评论中指出的那样,编译器完全有可能自动优化这种结构。人们必须进行测试和基准测试才能确定。