簡(jiǎn)介
protobuf是google開源的數(shù)據(jù)傳輸格式,作用類似于json/xml
github地址https://github.com/protocolbuffers/protobuf
效率
由于protobuf采用二進(jìn)制編碼,不同于json/xml,其編碼后的格式不便于人為觀察,用于對(duì)傳輸效率/網(wǎng)絡(luò)包等有特殊要求的服務(wù),目前截止發(fā)文,已經(jīng)支持了C++/java/go/js/python等10中語(yǔ)言,下圖,換句話說(shuō),除了以上語(yǔ)言,其他語(yǔ)言暫時(shí)還用不了prototbuf編碼.
有利有弊,在犧牲可讀性的同時(shí),其可以獲取更高的效率,根據(jù)這篇博客作者的實(shí)際測(cè)試,其結(jié)果如下
結(jié)構(gòu)體{"phone":{"phoneName":"idol3","price":2000,"top":1},"watch":{"watchName":"tcl wtch","top":1,"price":1000}}
1個(gè)結(jié)構(gòu)體測(cè)試
-
空間效率
- Json:107個(gè)字節(jié)
- Protobuf:32個(gè)字節(jié)
-
時(shí)間效率
- Json序列化: 1ms , 反序列化:0ms
- Protobuf 序列化: 0ms 反序列化:0ms
1000個(gè)結(jié)構(gòu)體測(cè)試
-
空間效率
- Json:4206個(gè)字節(jié)
- Protobuf:1332個(gè)字節(jié)
-
時(shí)間效率
- Json序列化: 4ms , 反序列化:1ms
- Protobuf 序列化: 1ms 反序列化:0ms
定義
protobuf最基礎(chǔ)的使用就是寫一個(gè)配置文件,這個(gè)文件定義了我要傳輸?shù)臄?shù)據(jù)是什么樣子,比如我要傳一個(gè)文件大小,還有名字,那么這個(gè)文件就可以定義為
syntax = "proto2";//可選proto2,proto3
package file;
message file
{
required int32 id = 1;
required string name = 2;
optional int32 size = 3;
}
其中:
- stntax就是要定義的proto版本,目前僅有兩個(gè)版本可選,兩個(gè)版本生成的代碼不同
- package就是包名,和golang中定義的包名一個(gè)意思,在c++里應(yīng)該會(huì)變成命名空間
- message就是對(duì)應(yīng)golang里的一個(gè)結(jié)構(gòu)體,或者說(shuō)要傳輸?shù)奈募钚挝?類似于json里的一個(gè)對(duì)象,在golang里會(huì)變成一個(gè)結(jié)構(gòu)體,java里是一個(gè)類,c++里也是一個(gè)結(jié)構(gòu)體應(yīng)該,具體還沒(méi)測(cè)試
- 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ù)組
使用
使用來(lái)講主要是用prorotc
上github源碼,download下來(lái),按說(shuō)明進(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
其他語(yǔ)言類似,然后將生成的.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/