文字だけのMessagePack風シリアライザ「AsciiPack」を書いた

きっかけは@miyagawaさんのpodcastだった。

それまでMessagePackのことは知らなくて、その時に調べた段階ではJSONをバイナリでどうこうするというフワフワした情報だけしかわかってなかった。

それからアンテナ効果なのかMessagePackの情報が次々と入ってくるので試しにMessagePackの仕様を順守したjavascriptコードを書いてみてAjaxで通信させてみたらあっさりとはできなかった。javascriptがそもそもバイナリを文字として扱えないからだった。typed arrayやbase64エンコードで扱えなくもないけれどそれは何も知らない僕みたいなユーザーは使用を躊躇してしまうには十分な理由になった。

というわけでいっちょMessagePackとはなんぞやということを徹底的に理解しつつ現状のwebブラウザで扱いやすくするために0-9a-zA-Zの62文字だけで構成された劣化MessagePackを書いてみたらどうなるかなという理由でAsciiPack(他の名前候補はStringPack,Base62Packなど……)を開発した。

 仕様はMessagePackの型情報であるバイナリをアルファベットに置き換え型の種類もだいぶ省略したものにした。

{"compact"=>true,"binary"=>0}

JSON : "{\"compact\":true,\"binary\":0}" MessgePack : "\x82\xA7compact\xC3\xA6binary\x00"
AsciiPack : "r2NcompactYMbinary0"

MessagePackは言わば1バイトあたり256種フルの記号から構成できるのにAsciiPackでは1バイトあたりたったの26+26+10=62種類記号から構成させなければならない。MessagePackのズルさすごさを垣間見ることができる。

 

AsciiPackのメリットについて考えてみる(作ってからだけど)。

AsciiPackはJSONと同じくURIjavascriptでの扱いが楽だ。JSONに対しては文字列だけの場合を除いて長さが短いことが有用性になると思う。

これでシリアライズ・デシリアライズ速度がJSONを上回っていればいいんだけど現状は2倍から10倍は時間がかかってしまうのでここは課題。

現状いいところはないけれど、解りやすく扱いやすいJSONと早くて小さいMessagePackの間を隙間産業的に狙って行きたいなと思う。

 

作ったことによって新しいソリューションを得たというよりも、自分の勉強になったことのほうが大きい。これまで文字エンコードに対する理解が適当だったけど、ビット列に対する解釈方法の一つとして見ることができた。またJSONは使用しているバイト情報としては無駄が多いということもわかった。mapのために2文字2バイト、arrayに2文字2バイト、文字列で1文字2バイト、型情報のために使用してるバイト情報としては5/256しか使用していない。あとはシリアライズ形式は割と簡単に作れてしまうこともわかったし、型システムへの興味もわいた。これまで動的言語ばかり扱ってきたにわかプログラマーなゆえに「型なんてかったるい!」と考えていたけど効率よくビット情報を解釈するための共通テンプレートとしての有用性を理解できた。

 

というわけで皆さんMessagePackを使いましょう。

 

===

https://github.com/ksss/AsciiPack

http://msgpack.org/

http://rebuild.fm/3/