Carpe Diem

備忘録

GoGo Protobufのメリット・デメリット

概要

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に対応した公式モジュールとのパフォーマンス比較が以下の記事ではされていますが、

tonybai.com

こちらでもgogo protobufの方が性能が良いという結果になりました。

Goの文法に則ったコードを生成できる

GoではidIDurlURLとするルールがあります。

しかし公式のライブラリではIdUrlといったようにGoのinitialismsのルールとは異なる状態で生成されます。

github.com

gogo protobufではextensionのcustomnameを使うことでそういったGo的に正しい名前へ修正することができます。

message User {
    string id   = 1 [(gogoproto.customname) = "ID"];
    string name = 2;
}

他にもpointerでない形や、埋込み型でコード生成できたりなど、多様なカスタマイズが可能です。

デメリット

デメリットとしては公式でない点による影響です。

gRPCのServer Reflectionが使えない

grpc/reflectiongolang/protobufと密結合になっており、protoc-gen-gogo*プラグインを使うとコード生成はできるもののServer Reflectionはうまく動きません。

github.com

protoc-gen-gofast単体あればServer Reflectionは使えますが、extensionを導入しようとすると動かなくなります。

メンテされなくなりそう

github.com

要約するとProtobuf API v2対応は長期的にはgogo protobufにとっても良いが、現在作業を引き受ける人がいないので頓挫しそう。とのこと。

まとめ

以前から使っていたgogo protobufですが、今現在は分水嶺に立つ状態になっています。
まだ不安定な公式のv2にするのは早計ですが、今後gogo protobufメンテナーが現れない限りいずれ移行が必要になりそうです。

ソース