Rubyで中間データをディスクにダンプする場合
require 'yaml'
File.open('hoge.yaml', 'w') { |f|
f.write(hoge.to_yaml)
}
とやって保存したものを
require 'yaml'
hoge = YAML.load_file 'hoge.yaml'
などと書くことで、ディスクとメモリを容易に行き来できます。
yamlは人間の目にも比較的読みやすいため便利です。
MessagePack + LZMA圧縮
クローラなどで大規模なデータを処理する場合、ディスクの専有サイズが問題になることがよくあります。
そこでmsgpack+lzmaを使う事で従来より飛躍的にサイズを縮小することができます。
msgpackはJSONに近いセマンティクスを提供するオブジェクトのバイナリフォーマットです。バイナリである上、小さい数値データや真偽値などの保存に特に効果を発揮するフォーマットになっています。
lzmaは比較的最近開発された圧縮形式で、gzipよりは遅い圧縮速度と高い圧縮効率、圧縮効率の割に高速な展開速度を誇ります。(bz2の方が圧縮率では一枚上手だけど展開が遅すぎる)
msgpack, lzma共にRubyのネイティブエクステンションの形で提供されているため非常に高速です。
まずインストールは
$ gem install ruby-lzma
$ gem install msgpack
で行えます。そして
require 'msgpack'
require 'lzma'
File.open('hoge.dump', "w") {|f|
f.write LZMA.compress(hoge.to_msgpack)
}
のようにしてファイルに書き出せます。書いたものは
hoge = MessagePack.unpack(LZMA.decompress(File.read('hoge.dump')))
のように読み出せます。
サイズ比較
たまたま僕の手元に過去の一定時間のツイートを集めたjsonファイルが1MB近くあるのでこれを圧縮保存した物を比較します。
-rw-r--r-- 1 kumagi kumagi 917013 9月 17 09:53 tweets.json # 元ファイル:ツイートのJSONデータ
-rw-r--r-- 1 kumagi kumagi 962256 9月 17 09:57 tweets.yaml # ↑のデータをYAMLにしたもの
-rw-r--r-- 1 kumagi kumagi 85998 9月 17 10:04 tweets.dump # ↑のデータをmsgpack+lzmaにしたもの
マーベラス。
大差ない記述量で使用するディスク領域が1/10以下になっています。
ダンプのデータを人間が目視で読めないという点を除いて、先に記述したYAMLの時と同様の使い勝手で利用できるのでおすすめです。