簡介
protobuf是google開源的數(shù)據(jù)傳輸格式,作用類似于json/xml
github地址https://github.com/protocolbuffers/protobuf
效率
由于protobuf采用二進(jìn)制編碼,不同于json/xml,其編碼后的格式不便于人為觀察,用于對傳輸效率/網(wǎng)絡(luò)包等有特殊要求的服務(wù),目前截止發(fā)文,已經(jīng)支持了C++/java/go/js/python等10中語言,下圖,換句話說,除了以上語言,其他語言暫時還用不了prototbuf編碼.
有利有弊,在犧牲可讀性的同時,其可以獲取更高的效率,根據(jù)這篇博客作者的實(shí)際測試,其結(jié)果如下
結(jié)構(gòu)體{"phone":{"phoneName":"idol3","price":2000,"top":1},"watch":{"watchName":"tcl wtch","top":1,"price":1000}}
1個結(jié)構(gòu)體測試
-
空間效率
- Json:107個字節(jié)
- Protobuf:32個字節(jié)
-
時間效率
- Json序列化: 1ms , 反序列化:0ms
- Protobuf 序列化: 0ms 反序列化:0ms
1000個結(jié)構(gòu)體測試
-
空間效率
- Json:4206個字節(jié)
- Protobuf:1332個字節(jié)
-
時間效率
- Json序列化: 4ms , 反序列化:1ms
- Protobuf 序列化: 1ms 反序列化:0ms
定義
protobuf最基礎(chǔ)的使用就是寫一個配置文件,這個文件定義了我要傳輸?shù)臄?shù)據(jù)是什么樣子,比如我要傳一個文件大小,還有名字,那么這個文件就可以定義為
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++里應(yīng)該會變成命名空間
- message就是對應(yīng)golang里的一個結(jié)構(gòu)體,或者說要傳輸?shù)奈募钚挝?類似于json里的一個對象,在golang里會變成一個結(jié)構(gòu)體,java里是一個類,c++里也是一個結(jié)構(gòu)體應(yīng)該,具體還沒測試
- int32/string好解釋,就是數(shù)據(jù)類型,proto支持好多數(shù)據(jù)類型,參考附錄[1]
- id/name/size 就是字段的名字,
- 1/2/3就是編碼值,一般就是按順序?qū)?便于proto進(jìn)行編碼
- 最后require/option/repeated,require代表該字段出現(xiàn)次數(shù)為1,option代表該字段出現(xiàn)次數(shù)為01,repeated代表該字段出現(xiàn)次數(shù)為0n,也就是數(shù)組
使用
使用來講主要是用prorotc
上github源碼,download下來,按說明進(jìn)行./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)導(dǎo)入項(xiàng)目中進(jìn)行使用即可,比如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"
...
附錄
本文摘自 :https://www.cnblogs.com/