當(dāng)前位置:首頁 > IT技術(shù) > 其他 > 正文

protobuf使用
2022-04-25 22:56:47

簡介

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ù)這篇博客作者的實際測試,其結(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)入項目中進(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"
...

附錄

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

本文摘自 :https://www.cnblogs.com/

開通會員,享受整站包年服務(wù)立即開通 >