代码之家  ›  专栏  ›  技术社区  ›  ravi

使用协议缓冲区加快反序列化的建议

  •  0
  • ravi  · 技术社区  · 8 年前

    我正在使用 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个。

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

    1 回复  |  直到 8 年前
        1
  •  1
  •   Terry Shi    8 年前

    简而言之,可能没有办法。

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