萌えハッカーニュースリーダー

2025/07/17 10:09 Parsing Protobuf Like Never Before

hakase
博士

ロボ子、新しいProtobufライブラリ「hyperpb」が出たみたいじゃぞ!Goで書かれていて、UPBの最適化を取り入れているらしい。

roboko
ロボ子

UPBの最適化をGoにですか。それは興味深いですね。なぜまた、UPBを再発明する必要があったのでしょう?

hakase
博士

それが、GoのC FFI(cgo)の制約が大きかったみたいじゃな。メモリ管理とかGCとか、色々面倒みたいじゃ。

roboko
ロボ子

なるほど。GoのレジスタABIや、UB(未定義動作)の少なさも関係しているようですね。

hakase
博士

そうそう!Goのエコシステムは起動時間を許容するから、オンラインPGO(プロファイルに基づく最適化)もできるのが大きいみたいじゃぞ。

roboko
ロボ子

hyperpbのAPIについてですが、「メッセージ記述子を受け取り、protoreflect型APIを実装する*hyperpb.MessageTypeを返す関数hyperpb.Compile*がある」とありますね。コンパイルはコストがかかるため、キャッシュが推奨されているとのこと。

hakase
博士

ふむふむ。コンパイラ、アンマーシャリング、プロファイル記録のためのパフォーマンス調整ノブもあるみたいじゃな。PGOは実装の詳細に影響を与える、と。

roboko
ロボ子

実装の詳細を見ると、コア実装はinternal/tdpにあるようですね。tdpはインタープリターのオブジェクトコード形式を定義し、tdp/compilerがprotoreflect.MessageDescriptorをtdp.Libraryに変換すると。

hakase
博士

tdp.Typeは、ルートメッセージから到達可能なすべてのMessageDescriptorになるんじゃな。フィールドのオフセットとアクセッササンクを含む、と。

roboko
ロボ子

tdp.TypeParserはエンコードされたProtobufデータを解釈し、tdp.FieldParserはフィールドのタグ、関数ポインタ、次のフィールドを含む、とありますね。

hakase
博士

フィールドスケジューリングで、フィールドの順序に基づいて試す順序を決定するんじゃな。賢い!

roboko
ロボ子

Parser VMも興味深いです。パーサーの状態はvm.P1とvm.P2の2つの型に分割された8つの64ビット整数で構成されている、と。

hakase
博士

仮想関数呼び出しは分岐予測が容易だから高速、か。メッセージは少数のフィールドアーキタイプを使用するから、CPUは間接ジャンプを予測しやすい、と。

roboko
ロボ子

ゼロコピー文字列、繰り返しプリロード、マップの最適化、アリーナの再利用、Oneofユニオンなど、様々な最適化が施されているようですね。

hakase
博士

Goの組み込みマップのオーバーヘッドを避けるために、カスタム実装を使うとは、徹底しておるのじゃ!

roboko
ロボ子

アリーナをリセットして、最大のメモリブロックを再割り当てのために保持するのも、効率的ですね。

hakase
博士

OneofユニオンでGoのユニオンの制限を回避するために、アリーナポインタを整数としてアリーナに格納するとは…すごい工夫じゃ!

roboko
ロボ子

hyperpb、かなり期待できそうですね。Bufのprotovalidateライブラリでの利用が想定されているとのことなので、今後の動向に注目したいです。

hakase
博士

ほんとじゃな!しかし、これだけ最適化されていると、私の脳みそも最適化されて、何も考えなくなるかもしれん…って、それは困るのじゃ!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search