`google.golang.org/protobuf/encoding/protojson` 是 Go 語言中的一個庫,用於處理 Protocol Buffers(protobuf)和 JSON 之間的轉換,遵循[https://protobuf.dev/programming-guides/pr ...
google.golang.org/protobuf/encoding/protojson
是 Go 語言中的一個庫,用於處理 Protocol Buffers(protobuf)和 JSON 之間的轉換,遵循https://protobuf.dev/programming-guides/proto3#json實現。
以下是該庫的一些主要功能:
- 將 protobuf 消息轉換為 JSON 格式:這是通過
Marshal
或MarshalOptions.Marshal
函數實現的。這些函數接收一個 protobuf 消息並返回一個 JSON 格式的字元串。 - 將 JSON 格式的數據轉換為 protobuf 消息:這是通過
Unmarshal
或UnmarshalOptions.Unmarshal
函數實現的。這些函數接收一個 JSON 格式的字元串和一個 protobuf 消息的指針,然後將 JSON 數據解析並填充到 protobuf 消息中。 - 自定義 JSON 編碼和解碼的行為:
MarshalOptions
和UnmarshalOptions
結構體提供了一些選項,可以用來自定義 JSON 編碼和解碼的行為。例如,可以通過EmitUnpopulated
選項控制是否輸出未設置的欄位,通過UseProtoNames
選項控制是否使用 protobuf 欄位的原始名稱作為 JSON 欄位的鍵。 - 支持 Well-Known Types:該庫提供了對 protobuf 的 Well-Known Types 的特殊處理,例如
Timestamp
、Duration
、Struct
、Value
等。
接下來我們以下麵的 .proto
為例,介紹下如何使用 google.golang.org/protobuf/encoding/protojson
,並簡單對比下 proto
、 protojson
和 encoding/json
三者之間的性能對比:
syntax = "proto3";
package example.pb;
option go_package = "./;pb";
import "google/protobuf/struct.proto";
message Base {
string tx_hash = 1;
int64 timestamp = 2;
google.protobuf.Struct extra = 3;
uint64 block_number = 4;
int32 category = 5;
}
message CertGen {
string id = 1;
string issuer = 2;
string name = 3;
string number = 4;
string seal_name = 5;
string seal_number = 6;
string sign_hash = 7;
string date = 8;
Base base = 9;
}
func genData() *pb.CertGen {
data := map[string]interface{}{
"name": "1234",
"age": 12,
"score": 1345.452434,
}
extra, _ := structpb.NewStruct(data)
base := &pb.Base{
TxHash: "1234556",
Timestamp: 1234566,
Extra: extra,
BlockNumber: 123456,
Category: 4,
}
return &pb.CertGen{
Id: uuid.NewString(),
Issuer: uuid.NewString(),
Name: uuid.NewString(),
Number: uuid.NewString(),
SealName: uuid.NewString(),
SealNumber: uuid.NewString(),
SignHash: uuid.NewString(),
Date: time.Now().Format(time.DateTime),
Base: base,
}
}
func BenchmarkProto(b *testing.B) {
gen := genData()
for i := 0; i < b.N; i++ {
proto.Marshal(gen)
}
}
func BenchmarkProtoJson(b *testing.B) {
gen := genData()
for i := 0; i < b.N; i++ {
protojson.Marshal(gen)
}
}
func BenchmarkStdJson(b *testing.B) {
gen := genData()
for i := 0; i < b.N; i++ {
json.Marshal(gen)
}
}
結果如下:
$ go test -bench=.
goos: linux
goarch: amd64
pkg: example
cpu: 12th Gen Intel(R) Core(TM) i7-1260P
BenchmarkProto-16 817065 1412 ns/op
BenchmarkProtoJson-16 218583 5372 ns/op
BenchmarkStdJson-16 343822 3216 ns/op
PASS
ok example 3.554s
聲明:本作品採用署名-非商業性使用-相同方式共用 4.0 國際 (CC BY-NC-SA 4.0)進行許可,使用時請註明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無意