せっかくなのでデフォルト(YAML)、Oj(json)、MessagePackでベンチマークも取ってみました。
保存するデータは http://json-generator.appspot.com/ ここで適当に作ったものをロードして突っ込んでます。
DBに保存していたりしますが、単純にそれぞれのdumpとloadの差です。
migration
create_table :articles, force: true do |t|
t.column :body, "MEDIUMTEXT", null: false
t.timestamps null: false
end
create_table :oj_articles, force: true do |t|
t.column :body, "MEDIUMTEXT", null: false
t.timestamps null: false
end
create_table :msgpack_articles, force: true do |t|
t.column :body, "MEDIUMBLOB", null: false
t.timestamps null: false
end
MessagePackはバイナリデータなので、BLOB型にしています。
models
class SerializationOj
def self.dump(obj)
Oj.dump(obj, mode: :compat)
end
def self.load(json)
Oj.load(json, mode: :compat) unless json.nil?
end
end
class SerializationMessagePack
def self.dump(obj)
MessagePack.pack(obj)
end
def self.load(binary)
MessagePack.unpack(binary) unless binary.nil?
end
end
class Article < ActiveRecord::Base
serialize :body
end
class OjArticle < ActiveRecord::Base
serialize :body, SerializationOj
end
class MsgpackArticle < ActiveRecord::Base
serialize :body, SerializationMessagePack
end
MessagePackのシリアライズクラスを作ってserializeの第2引数に指定
benchmark
BENCH_TIMES = 10000
BODY_DATA = Oj.load(File.read(File.expand_path("../dummy.json", __FILE__)), mode: :compat)
p "file size: #{BODY_DATA.size}"
Benchmark.bmbm do |bm|
p "yaml"
bm.report "create" do
BENCH_TIMES.times do
Article.create!(body: BODY_DATA)
end
end
bm.report "find" do
BENCH_TIMES.times do
Article.limit(100).collect(&:body)
end
end
end
Benchmark.bmbm do |bm|
p "oj"
bm.report "create" do
BENCH_TIMES.times do
OjArticle.create!(body: BODY_DATA)
end
end
bm.report "find" do
BENCH_TIMES.times do
OjArticle.limit(100).collect(&:body)
end
end
end
Benchmark.bmbm do |bm|
p "msgpack"
bm.report "create" do
BENCH_TIMES.times do
MsgpackArticle.create!(body: BODY_DATA)
end
end
bm.report "find" do
BENCH_TIMES.times do
MsgpackArticle.limit(100).collect(&:body)
end
end
end
result
"file size: 87505"
"yaml"
Rehearsal ------------------------------------------
create 194.760000 4.410000 199.170000 (226.059458)
find 1443.380000 145.550000 1588.930000 (1691.537545)
------------------------------ total: 1788.100000sec
user system total real
create 194.280000 4.370000 198.650000 (249.059130)
find 1443.510000 145.030000 1588.540000 (1690.263404)
"oj"
Rehearsal ------------------------------------------
create 50.360000 3.440000 53.800000 ( 83.307643)
find 392.770000 137.870000 530.640000 (633.403793)
------------------------------- total: 584.440000sec
user system total real
create 50.550000 3.320000 53.870000 (116.603378)
find 393.820000 138.790000 532.610000 (635.451361)
"msgpack"
Rehearsal ------------------------------------------
create 13.390000 3.490000 16.880000 ( 39.246475)
find 75.450000 103.490000 178.940000 (268.235375)
------------------------------- total: 195.820000sec
user system total real
create 15.200000 3.670000 18.870000 (147.845164)
find 75.580000 104.860000 180.440000 (269.350645)
MsagePack速い!