• protobuf


     韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha

    Protocol Buffers ”(简称protobuf)

    这个东东干的事儿其实和XML 差不多,也就是把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合。

    为啥放着好端端的XML不用,非要另起炉灶,重新造轮子。一个根本的原因是XML性能不够好。
      先说时间开销:XML格式化(序列化)的开销倒还好;但是XML解析(反序列化)的开销就不敢恭维啦。俺之前经常碰到一些时间性能很敏感的场合,由于不堪忍受XML解析的速度,弃之如敝履。
      再来看空间开销:熟悉XML语法的同学应该知道,XML格式为了有较好的可读性,引入了一些冗余的文本信息。所以空间开销也不是太好(不过这点缺点,俺不常碰到)。

    除了性能好,代码生成机制是主要吸引俺的地方。为了说明这个代码生成机制,俺举个例子。
      比如有个电子商务的系统(假设用C++实现),其中的模块A需要发送大量的订单信息给模块B,通讯的方式使用socket。
    假设订单包括如下属性:
    --------------------------------
      时间:time(用整数表示)
      客户id:userid(用整数表示)
      交易金额:price(用浮点数表示)
      交易的描述:desc(用字符串表示)
    --------------------------------
      如果使用protobuf实现,首先要写一个proto文件(不妨叫Order.proto),在该文件中添加一个名为"Order"的message结构,用来描述通讯协议中的结构化数据。该文件的内容大致如下:

    --------------------------------

    message Order
    {
      required int32 time = 1;
      required int32 userid = 2;
      required float price = 3;
      optional string desc = 4;
    }

    --------------------------------


      然后,使用protobuf内置的编译器编译 该proto。由于本例子的模块是C++,你可以通过protobuf编译器的命令行参数(看“这里 ”),让它生成C++语言的“订单包装类”。(一般来说,一个message结构会生成一个包装类)
      然后你使用类似下面的代码来序列化/解析该订单包装类:


    --------------------------------

    // 发送方

    Order order;
    order.set_time(XXXX);
    order.set_userid(123);
    order.set_price(100.0f);
    order.set_desc("a test order");

    string sOrder;
    order.SerailzeToString(&sOrder);

    // 然后调用某种socket的通讯库把序列化之后的字符串发送出去
    // ......

    --------------------------------

    // 接收方

    string sOrder;
    // 先通过网络通讯库接收到数据,存放到某字符串sOrder
    // ......

    Order order;
    if(order.ParseFromString(sOrder))  // 解析该字符串
    {
      cout << "userid:" << order.userid() << endl
              << "desc:" << order.desc() << endl;
    }
    else
    {
      cerr << "parse error!" << endl;
    }

    --------------------------------

     有了这种代码生成机制,开发人员再也不用吭哧吭哧地编写那些协议解析的代码了(干这种活是典型的吃力不讨好)。
      万一将来需求发生变更,要求给订单再增加一个“状态”的属性,那只需要在Order.proto文件中增加一行代码。对于发送方(模块A),只要增加一行设置状态的代码;对于接收方(模块B)只要增加一行读取状态的代码。哇塞,简直太轻松了!

  • 相关阅读:
    WPS项目编号问题
    Allegro转换PADS终极篇(转载)
    Allegro16.3约束设置 (转载)
    转:浮点数在计算机中存储方式
    转:十进制小数转化为二进制小数
    变量的存储类别 内部函数和外部函数
    关于Nios II的启动分析(转载)
    Allegro学习(http://www.asmyword.com/forum.php?mod=forumdisplay&fid=86)
    cf1113 C. Sasha and a Bit of Relax
    D. Jongmah cf1110
  • 原文地址:https://www.cnblogs.com/yue31313/p/7362244.html
Copyright © 2020-2023  润新知