okayurisotto.net

私が好きでやったことが他の人のためにもなったらお得かも!

JSONよりMessagePackの方が処理が速いこともある

  1. 📝

はじめに

現代においてデータ形式として最もよく使われているものはおそらくJSONでしょう。人間にとっても機械にとってもある程度読み書きがしやすいJSONは、WebとともにJavaScriptが普及することで、多くの場面で使われるようになりました。

この記事では、そんなJSONと、JSONよりも高速に処理できると噂されているMessagePackについてまとめます。

JSONについて

JSONとは、JavaScript Object Notationの略であるその名が示す通り、JavaScriptで使われていたオブジェクト表記法から影響を受けたデータ形式(オブジェクトシリアライズフォーマット)です。前述のように現代でよく使われているデータ形式であり、様々なプログラミング言語でサポートされています。それゆえ、Webを介さないデータ交換にも便利な形式でしょう。(まぁこの辺りの話は、鶏と卵の話になってしまうのですが……。)

データをテキストとして表現するため、人間にとってある程度の読みやすさがあります。またその構文は厳密に定まっており、パーサーもある程度簡単に書くことができます(できました)。

MessagePackについて

対するMessagePackはバイナリで記述するデータ形式です。それゆえ人間による読み書きは想定されていませんが、JSONよりデータ容量的にも処理的にも効率がよいとされています。

JSONの代替として使うことができ、JSONとの相互変換が可能です。それだけでなく、JSONでは表現できないタイムスタンプのようなデータも表現でき、非常に便利です。流石にJSONほどサポートが手厚いわけではないものの多くのプログラミング言語でサポートされていることがMessagePack公式サイトでアピールされています。

人間による読み書きが想定されていないという点はJSONに対するデメリットとしてありますが、そもそものJSON自体、書きたいという人間はそう多くないでしょう。ほとんどの人はより書きやすいYAMLやTOMLを選ぶでしょうし、そこまでいかなくともJSONCやJSON5などを使うでしょう。

ベンチマーク

さて、MessagePackはJSONより処理が速いということでしたが、本当でしょうか? 例えばJavaScriptの場合、JSONを扱う機能は、JSON.parse関数やJSON.stringify関数としてJavaScript自体に組み込まれています。対するMessagePackを扱う機能はJavaScriptの上で実装されています。

実際に処理時間にどの程度の差が生まれるものなのでしょうか。気になったのでベンチマークを測ってみました。

具体的なベンチマーク方法や使ったデータなどはリポジトリをご覧いただくとして、ここでは簡単にまとめます。

まず、29916897文字のJSONファイルをjisyo.jsonとして用意しました。そしてそれにminificationを施すことで16197288文字(容量にして58%)にしたjisyo.min.jsonを用意しました。またそれとは別にMessagePackにすることで容量を44%まで減らしたjisyo.msgpackを用意しました。

そしてそれぞれを、TypeScript実行環境であるDenoを使って読み込んでみました。ここで言う「読み込み」とは、ファイルに書かれた内容を、プログラミング言語が扱う普通の形式(オブジェクトに変換することです。

結果は次のようになりました。

# ファイルの読み込みのみ
read: jisyo.json                             5.3 ms
read: jisyo.min.json                        2.85 ms
read: jisyo.msgpack                         1.84 ms

# JSONの場合必要になる、読み込んだファイルの内容の文字列への変換
read + stringify: jisyo.json               68.91 ms
read + stringify: jisyo.min.json           47.38 ms

# 文字列(JSONの場合)/バイナリ(MessagePackの場合)のオブジェクトへの変換
read + stringify + parse: jisyo.json      254.28 ms
read + stringify + parse: jisyo.min.json  215.79 ms
read + parse: jisyo.msgpack               173.08 ms

おわりに

単純なファイル読み込み速度に関しても、JSONよりminified JSONよりMessagePackが速いようでしたが、これだけ大きなデータでも数msの差に留まりました。また、JSONとminified JSONで必要になる文字列化の処理にはそこそこの時間がかかるようです。ファイルから読み込んだデータのオブジェクト化にはさらに時間がかかりました。ただそれでも、JSONよりminified JSONよりMessagePackのほうが速いという結果でした。

人間にとっての読み書きのしやすさ(≒デバッグのやりやすさなど)は犠牲になってしまいますが、MessagePackの処理速度及びファイル容量の削減効果はかなり有用なものであると感じました。実際にこれだけ大きなデータをファイルとして保存して扱うことはそうそうないと思われますが(データベースなどを使うべき場面であると考えられるため)、それでもやはりMessagePackは有用でしょう。

人間にとっても機械にとってもある程度読み書きがしやすいJSONが中途半端という話はしないでおきましょうか……。