概要
Goでprotobufのコードを生成する際には公式のgolang/protbuf以外にgogo/protobufが候補に挙がると思います。
メリット
大きなメリットはパフォーマンスとカスタマイズ性です。
marshalling と unmarshalling が高速
去年のベンチマークですが、公式より2.5~3倍近くパフォーマンスが良いことがわかります。
benchmark | iter | time/iter | bytes/op | allocs/op |
---|---|---|---|---|
BenchmarkGoprotobufMarshal-8 | 5000000 | 337 ns/op | 96 | 2 |
BenchmarkGoprotobufUnmarshal-8 | 3000000 | 533 ns/op | 200 | 10 |
BenchmarkGogoprotobufMarshal-8 | 10000000 | 132 ns/op | 64 | 1 |
BenchmarkGogoprotobufUnmarshal-8 | 10000000 | 187 ns/op | 96 | 3 |
2019-08-28 Results with Go 1.12.6 darwin/amd64 on a 2.8 GHz Intel Core i7 16GB
ref: GitHub - alecthomas/go_serialization_benchmarks: Benchmarks of Go serialization methods
またProtobuf API v2に対応した公式モジュールとのパフォーマンス比較が以下の記事ではされていますが、
こちらでもgogo protobufの方が性能が良いという結果になりました。
Goの文法に則ったコードを生成できる
Goではid
をID
、url
をURL
とするルールがあります。
しかし公式のライブラリではId
やUrl
といったようにGoのinitialismsのルールとは異なる状態で生成されます。
gogo protobufではextensionのcustomname
を使うことでそういったGo的に正しい名前へ修正することができます。
message User { string id = 1 [(gogoproto.customname) = "ID"]; string name = 2; }
他にもpointerでない形や、埋込み型でコード生成できたりなど、多様なカスタマイズが可能です。
デメリット
デメリットとしては公式でない点による影響です。
gRPCのServer Reflectionが使えない
grpc/reflectionがgolang/protobufと密結合になっており、protoc-gen-gogo*
系プラグインを使うとコード生成はできるもののServer Reflectionはうまく動きません。
protoc-gen-gofast
単体あればServer Reflectionは使えますが、extensionを導入しようとすると動かなくなります。
メンテされなくなりそう
要約するとProtobuf API v2対応は長期的にはgogo protobufにとっても良いが、現在作業を引き受ける人がいないので頓挫しそう。とのこと。
まとめ
以前から使っていたgogo protobufですが、今現在は分水嶺に立つ状態になっています。
まだ不安定な公式のv2にするのは早計ですが、今後gogo protobufメンテナーが現れない限りいずれ移行が必要になりそうです。