MessagePackをPythonで使ってみる
背景
仕事でMessagePackを使う機会があるので理解を深めたい
ゴール
環境
- Type: Mac mini
- OS: OS X Yosemite (10.10.2)
- CPU: 2.6 GHz Intel Core i7
- Memory: 16 GB 1600 MHz DDR3
- Graphics: Intel HD Graphics 4000 1024 MB
- Python: 2.7.8
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が他と比べて早くなっています。