Google protocol buffers compare

2019-02-04 09:28发布

问题:

I want to compare two Messages or (two sub parameters) of Google protocol buffers. I don't find an API to achieve it.

Any ideas?

回答1:

You can use the class google::protobuf::util::MessageDifferencer for this. I think it's only available since v3.0.2:

Introduced new utility functions/classes in the google/protobuf/util directory:

  • MessageDifferencer: compare two proto messages and report their differences.

MessageDifferencer::Equals(msg1, msg2);



回答2:

Instead of using message.DebugString you could also do

std::string strMsg;
message.SerializeToString(&strMsg);

with both messages and then compare the two (binary) strings. I didn't test the performance but I assume that it is faster than comparing the human readable message strings returned by .DebugString(). +You can do that with the protobuf-lite library (while for message.DebugString you need the full version).



回答3:

You can rely on the fact that all of your protobuf messages inherit from the google::protobuf::MesageLite type, which in turn has everything you need to compare any two protobuf messages, regardless of if they are even of the same derived type:

bool operator==(const google::protobuf::MessageLite& msg_a,
                const google::protobuf::MessageLite& msg_b) {
  return (msg_a.GetTypeName() == msg_b.GetTypeName()) &&
      (msg_a.SerializeAsString() == msg_b.SerializeAsString());
}


回答4:

Well, a protocol buffer is just a serialization format for some object type. Why not use the protocol buffer to reconstruct the original objects, and then allow those objects to compare themselves, using whatever comparison logic you've built into the class?



回答5:

This might not be the ideal solution, but I think it could be done by:

messageA.DebugString() == messageB.DebugString();

Other than that, I think the only solution would be to create your own Message child class and implement a bool operator==(const Message&).



回答6:

You can compare the descriptor's pointer (super fast):

if (mMessages[i]->body()->GetDescriptor() == T::descriptor())

mMessages it's a pool of network messages with header and crypto which creates a packet with the protobuf body(google::protobuf::Message*).

so, to get the right kind of message i compare the descriptors constant pointer which is the same for every single type of message (not %100 sure but i haven't got any problem so far).

That would be the fastest way to compare a protobuf Message wthout having to use string comparasion, which by the way you gan get the type name from the descriptor. :-)