protobuf使用

简介

protobuf是google开源的数据传输格式,作用类似于json/xml
github地址https://github.com/protocolbuffers/protobuf

效率

由于protobuf采用二进制编码,不同于json/xml,其编码后的格式不便于人为观察,用于对传输效率/网络包等有特殊要求的服务,目前截止发文,已经支持了C++/java/go/js/python等10中语言,下图,换句话说,除了以上语言,其他语言暂时还用不了prototbuf编码.

有利有弊,在牺牲可读性的同时,其可以获取更高的效率,根据这篇博客作者的实际测试,其结果如下

结构体{phone:{phoneName:idol3,price:2000,top:1},watch:{watchName:tcl wtch,top:1,price:1000}}
1个结构体测试

  • 空间效率

    • Json:107个字节
    • Protobuf:32个字节
  • 时间效率

    • Json序列化: 1ms , 反序列化:0ms
    • Protobuf 序列化: 0ms 反序列化:0ms

1000个结构体测试

  • 空间效率

    • Json:4206个字节
    • Protobuf:1332个字节
  • 时间效率

    • Json序列化: 4ms , 反序列化:1ms
    • Protobuf 序列化: 1ms 反序列化:0ms

定义

protobuf最基础的使用就是写一个配置文件,这个文件定义了我要传输的数据是什么样子,比如我要传一个文件大小,还有名字,那么这个文件就可以定义为

syntax = proto2;//可选proto2,proto3  package file;  message file {    required int32 id = 1;      required string name = 2;      optional int32 size  = 3;   } 

其中:

  • stntax就是要定义的proto版本,目前仅有两个版本可选,两个版本生成的代码不同
  • package就是包名,和golang中定义的包名一个意思,在c++里应该会变成命名空间
  • message就是对应golang里的一个结构体,或者说要传输的文件最小单位,类似于json里的一个对象,在golang里会变成一个结构体,java里是一个类,c++里也是一个结构体应该,具体还没测试
  • int32/string好解释,就是数据类型,proto支持好多数据类型,参考附录[1]
  • id/name/size 就是字段的名字,
  • 1/2/3就是编码值,一般就是按顺序写,便于proto进行编码
  • 最后require/option/repeated,require代表该字段出现次数为1,option代表该字段出现次数为01,repeated代表该字段出现次数为0n,也就是数组

使用

使用来讲主要是用prorotc
上github源码,download下来,按说明进行./configure && make && make install就行
使用功能命令

#c++ protoc --cpp_out=$DST_DIR $SRC_DIR/file.proto #go protoc --go_out=$DST_DIR $SRC_DIR/file.proto 

其他语言类似,然后将生成的.h(c++)或.go(golang)导入项目中进行使用即可,比如golang

import github.com/golang/protobuf/proto  ... f := new(file) f.name = book data := proto.Marshal(f) //压缩  nf := new(file) proto.Unmarshal(nf,data) //解压 name := nf.getName() //name = book ... 

附录

  1. [https://www.jianshu.com/p/362a6cdb63c5]https://www.jianshu.com/p/362a6cdb63c5