[golang] MessagePackのシリアライザ(msgpack)を作りました

お世話になっております。
しゃまとんです。

ちょっとしたお知らせです。
タイトルの通りなんですが、golangで使えるMessagePackのシリアライザを作りました。
(🎉個人的にはパンパカパーン🎉)

まず、MessagePackとはデータのシリアライズフォーマットの1つで効率の良い形式として知られています。よくJSONと比較・検証されて使われていることが多いですね。
現在は多くの言語で使えるようになっており、言語間で何かデータのやり取りをするときに候補の1つになっています。

公式にもある通り、JSONよりも軽量で速いのが特徴です。

もちろんGo言語でもMessagePackが扱えるパッケージがすでにいくつか存在しており、使いたければ使える状況になっています。自分自身も使っていたのですが、とあるきっかけからpackageを覗いてみたところ、なんとなくもう少し速くできそうかなぁ…と思いました。

で、簡単な検証用ベンチマークコードを書いてみたところ、速くなりそうかなぁ…ということで書き始めたのが最初でした。コードを書き換えてはベンチマークを確認して…実装して…を繰り返しすすめていき、現在(2018.09時点)v1.0としてリリースできました。

エンドポイントの名称は迷ったんですが、いろいろ考えてEncode / Decodeにしました。
呼び出しはこんな感じで。

単純に使うだけならEncode/Decodeを呼び出すだけです!
引数は標準のパッケージencoding/jsonと同じ形にしてます。(置き換えが容易かも…!)

で、肝心のパフォーマンスですが、まずはシリアライズ。
自分が知っている範囲で他のMessagePackやJSON等の別フォーマットと比較してみます。ベンチマークはおそらくユーザーが呼び出すであろうエンドポイントでとってみました。

Shamatonとついているものが今回リリースしたものになります。ArrayShamatonというのはMessagePackのフォーマットが軽量なパターンを採用しているものです(UnityではMessagePack-CSharpでおなじみですね?)。今回のケースでは通常のEncodeでも他のパッケージよりも性能よく動作させられたっぽいです。

次にデシリアライズです。

こちらも性能良く動作させられたっぽいです。ただProtocol Bufferはデータの形次第でパフォーマンス良くなることがありました(struct onlyな構成など)。まぁprotoファイルとかを準備しないといけないので、その点よいかなーと。

結果を見る感じだとArray呼び出しがパフォーマンスがやはり良いので、使えるならAsArrayを使うのが良さそうかなと思います。ベンチマークですが、こちらにコードがあるので何かあれば教えてください。

ということで、単純な呼び出しでMessagePack系では割と速いシリアライザを作ることが出来ました。よかったよかった。それと今回の実装でzeroformatter側にも反映できそうなところもわかったので、対応できればなーと思っています。

あと余談ですが、タグでシリアライズ対象の設定ができたりとか、拡張エンコード・デコードにも対応させたりもしてます。(この辺はREADMEとかExampleに書く予定です)

よかったら使ってみてください!
以上です。