MessagePackをPythonで使ってみる

背景

仕事でMessagePackを使う機会があるので理解を深めたい

ゴール

  • PythonでMessagePackを試し、プロトコルのフォーマットを確認する
  • JSONとのパフォーマンス比較 (Serialization, Deserialization, サイズ)

環境

PythonでMessagePackをつかえるようにする

pipでインストールする

$ pip install msgpack-python

PythonでMessagePackを試し、プロトコルのフォーマットを確認する

フォーマットに関してはここにあるので参照しつつ確かめてみます。 ipythonで実行してみます

In [1]: import msgpack

In [11]: import binascii

In [21]: binascii.hexlify(msgpack.packb(None))
Out[21]: 'c0'

In [22]: binascii.hexlify(msgpack.packb(True))
Out[22]: 'c3'

In [23]: binascii.hexlify(msgpack.packb(False))
Out[23]: 'c2'

In [24]: binascii.hexlify(msgpack.packb(0))
Out[24]: '00'

In [25]: binascii.hexlify(msgpack.packb(-1))
Out[25]: 'ff'

In [32]: binascii.hexlify(msgpack.packb(127))
Out[32]: '7f'

In [33]: binascii.hexlify(msgpack.packb(128))
Out[33]: 'cc80'

上記を見ると、integerの場合は、127までは1byteで抑えていることがわかります。

In [60]: binascii.hexlify(msgpack.packb(''))
Out[60]: 'a0'

In [61]: binascii.hexlify(msgpack.packb('a'))
Out[61]: 'a161'

上記はstring。

In [34]: binascii.hexlify(msgpack.packb([0]))
Out[34]: '9100'

In [39]: binascii.hexlify(msgpack.packb([127]))
Out[39]: '917f'

In [40]: binascii.hexlify(msgpack.packb([128]))
Out[40]: '91cc80'

In [44]: binascii.hexlify(msgpack.packb([]))
Out[44]: '90'

arrayは9が先頭につき、つぎは要素の数を表しています。

In [70]: binascii.hexlify(msgpack.packb({}))
Out[70]: '80'

In [72]: binascii.hexlify(msgpack.packb({0:1}))
Out[72]: '810001'

上記はmap。

JSONとのパフォーマンス比較 (Serialization, Deserialization, サイズ)

こちらにあるベンチマークを実行してみます。 msgpackの関数が変わっていたので、packs, unpacksをそれぞれpackb, unpackbにかえてます。

$ python benchmark.py
== Integer ==
= Size =
pickle: 6203398 [bytes]
json:   5154816 [bytes]
mpack:  2752517 [bytes]
pickle_dump   188.917[ms]
pickle_load   302.937[ms]
json_dump     111.920[ms]
json_load     134.850[ms]
mpack_pack    22.618[ms]
mpack_unpack  23.949[ms]
== String ==
= Size =
pickle: 33731696 [bytes]
json:   33611776 [bytes]
mpack:  33595139 [bytes]
pickle_dump   171.892[ms]
pickle_load   95.018[ms]
json_dump     175.511[ms]
json_load     63.740[ms]
mpack_pack    51.335[ms]
mpack_unpack  15.441[ms]

Integerの場合はサイズが3分の1ほどになりますが、Stringの場合はあまりサイズは変わりません。 ただし、SerializationとDeserializationが他と比べて早くなっています。

参考

バイナリシリアライズ形式「MessagePack」