Google 协议缓冲区比较

发布于 2024-09-08 18:10:30 字数 178 浏览 3 评论 0原文

我想比较 Google 的两条消息或(两个子参数)协议缓冲区。 我没有找到 API 来实现它。

有什么想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

败给现实 2024-09-15 18:10:30

您可以使用类 google::protobuf:: util::MessageDifferencer 为此。我认为它仅自 v3.0.2 起可用:

在 google/protobuf/util 中引入了新的实用函数/类
目录:

  • MessageDifferencer:比较两个原始消息并报告它们的差异。
#include <google/protobuf/util/message_differencer.h>

MessageDifferencer::Equals(msg1, msg2);

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.
#include <google/protobuf/util/message_differencer.h>

MessageDifferencer::Equals(msg1, msg2);
一瞬间的火花 2024-09-15 18:10:30

您可以信赖这样一个事实:您的所有 protobuf 消息都继承自 google::protobuf::MesageLite 类型,该类型又具有比较任何两个 protobuf 消息所需的一切,无论它们是否属于相同的派生类型:

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());
}

< strong>编辑

正如下面的评论所指出的,特别是对于 map 字段,这个答案是不正确的。 map 元素具有不确定的排序。如果消息中可能存在 map 字段,请使用 MessageDifferencer

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());
}

EDIT

As was pointed out in the comments below, and especially for map fields, this answer is incorrect. map elements have non-deterministic ordering. Use MessageDifferencer if map fields might be present in your messages.

岁月染过的梦 2024-09-15 18:10:30

除了使用 message.DebugString 之外,您还可以同时处理

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

两条消息,然后比较两个(二进制)字符串。我没有测试性能,但我认为它比比较 .DebugString() 返回的人类可读消息字符串要快。 +您可以使用 protobuf-lite 库来做到这一点(而对于 message.DebugString 您需要完整版本)。

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).

物价感观 2024-09-15 18:10:30

好吧,协议缓冲区只是某些对象类型的序列化格式。为什么不使用协议缓冲区来重建原始对象,然后允许这些对象使用您在类中内置的任何比较逻辑来比较它们自己?

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?

-柠檬树下少年和吉他 2024-09-15 18:10:30

这可能不是理想的解决方案,但我认为可以通过以下方式完成:

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

除此之外,我认为唯一的解决方案是创建您自己的 Message 子类并实现 bool 运算符==(常量消息&)

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&).

强者自强 2024-09-15 18:10:30

您可以比较描述符的指针(超快):

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

mMessages 它是带有标头和加密的网络消息池,它创建带有 protobuf 主体的数据包(google::protobuf::Message*)。

因此,为了获得正确类型的消息,我比较了描述符常量指针,该指针对于每种类型的消息都是相同的(不确定%100,但到目前为止我还没有遇到任何问题)。

这将是比较 protobuf 消息的最快方法,而无需使用字符串比较,这样您就可以从描述符中获取类型名称。 :-)

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. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文