【问题标题】:Suggestions for faster deserialization using Protocol Buffers使用协议缓冲区更快反序列化的建议
【发布时间】:2017-12-20 09:01:20
【问题描述】:

我使用Protocol Buffers 来序列化/反序列化数据。我已将 Protocol Buffers 消息文件定义如下:

syntax = "proto3";
package Tutorial;
import "google/protobuf/timestamp.proto";

message PointCloud {
  int32 width  = 1;
  int32 height = 2;

  message Point {
    float x     = 1;
    float y     = 2;
    float z     = 3;
    fixed32 rgb = 4;
  }
  repeated Point points = 3;
  google.protobuf.Timestamp timestamp = 4;
}

我能够接收序列化数据。我正在使用ParseFromArray API 如下:

zmq::message_t msg;
int rc = zmq_socket.recv(&msg);
if (rc){
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    Tutorial::PointCloud point_cloud;
    point_cloud.ParseFromArray(msg.data(), msg.size());
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    std::cout << "Time (ms): " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()/1000.0 << std::endl
}  

上述方法有效,但反序列化数据需要足够的时间。在 Ubuntu 14.04 LTS 64 位操作系统中,平均需要大约 96 毫秒。仅供参考,我还打印了msg.size(),发现它大约是3773550。

我正在寻找比这更快的反序列化数据的建议。

【问题讨论】:

    标签: c++ serialization protocol-buffers


    【解决方案1】:

    简短的回答,可能没有办法。

    Protobuf 反序列化很慢,因为它需要从一系列键值对动态构建对象。如果您关心性能,请尝试使用 flatbuffer 或 Capn'Proto。这些替代方案不需要任何对象构造,但(可能)在磁盘上的成本更高,并且还有其他缺点。

    【讨论】:

    • 我明白了。非常感谢你。根据上面的代码和协议消息,您建议哪个? flatbuffer 还是 Capn'Proto ?我从来没有使用过它们中的任何一个。因此,我正在寻找专家的建议。
    • @RaviJoshi 两者都是可能的解决方案,我强烈建议您同时尝试并运行自己的基准测试。根据您的实际使用模型/模式,有太多的取舍。
    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多