gem | ||
---|---|---|
Json oj | 40.4 i/s | |
MessagePack | 38.3 i/s | same |
binary json | 22.0 i/s | 1.84x slower |
Json yajl | 19.0 i/s | 2.13x slower |
ruby json | 15.6 i/s | 2.59x slower |
ruby marshal | 13.9 i/s | 2.90x slower |
ruby yaml | 0.4 i/s | 111.99x slower |
Yaml Psych | 0.4 i/s | 112.09x slower |
ruby safe | 0.4 i/s | 113.66x slower |
-
-
Save kbrock/978baec148501587f8160864815c07ac to your computer and use it in GitHub Desktop.
Performance comparison of different ruby serializer methods
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- primitives only | |
marshal -- true | |
"\x04\b{\tI\"\tname\x06:\x06ETI\"\x13Fredrick Smith\x06;\x00TI\"\rquantity\x06;\x00Ti\x03@B\x0FI\"\tdate\x06;\x00TI\"\x1E2017-08-11 11:17:00 -0400\x06;\x00FI\"\x0Eaddresses\x06;\x00T{\aI\"\raddress1\x06;\x00TI\"612 Heather Street, Parnell, Auckland, New Zealand\x06;\x00TI\"\raddress2\x06;\x00TI\"/1 Queen Street, CBD, Auckland, New Zealand\x06;\x00T" | |
bson -- true | |
"\xD9\x00\x00\x00\x02name\x00\x0F\x00\x00\x00Fredrick Smith\x00\x10quantity\x00@B\x0F\x00\x02date\x00\x1A\x00\x00\x002017-08-11 11:17:00 -0400\x00\x03addresses\x00~\x00\x00\x00\x02address1\x002\x00\x00\x0012 Heather Street, Parnell, Auckland, New Zealand\x00\x02address2\x00+\x00\x00\x001 Queen Street, CBD, Auckland, New Zealand\x00\x00\x00" | |
msgpack -- true | |
"\x84\xA4name\xAEFredrick Smith\xA8quantity\xCE\x00\x0FB@\xA4date\xB92017-08-11 11:17:00 -0400\xA9addresses\x82\xA8address1\xD9112 Heather Street, Parnell, Auckland, New Zealand\xA8address2\xD9*1 Queen Street, CBD, Auckland, New Zealand" | |
json -- true | |
"{\"name\":\"Fredrick Smith\",\"quantity\":1000000,\"date\":\"2017-08-11 11:17:00 -0400\",\"addresses\":{\"address1\":\"12 Heather Street, Parnell, Auckland, New Zealand\",\"address2\":\"1 Queen Street, CBD, Auckland, New Zealand\"}}" | |
yajl -- true | |
"{\"name\":\"Fredrick Smith\",\"quantity\":1000000,\"date\":\"2017-08-11 11:17:00 -0400\",\"addresses\":{\"address1\":\"12 Heather Street, Parnell, Auckland, New Zealand\",\"address2\":\"1 Queen Street, CBD, Auckland, New Zealand\"}}" | |
oj -- true | |
"{\"name\":\"Fredrick Smith\",\"quantity\":1000000,\"date\":\"2017-08-11 11:17:00 -0400\",\"addresses\":{\"address1\":\"12 Heather Street, Parnell, Auckland, New Zealand\",\"address2\":\"1 Queen Street, CBD, Auckland, New Zealand\"}}" | |
yaml -- true | |
"---\nname: Fredrick Smith\nquantity: 1000000\ndate: '2017-08-11 11:17:00 -0400'\naddresses:\n address1: 12 Heather Street, Parnell, Auckland, New Zealand\n address2: 1 Queen Street, CBD, Auckland, New Zealand\n" | |
psych -- true | |
"---\nname: Fredrick Smith\nquantity: 1000000\ndate: '2017-08-11 11:17:00 -0400'\naddresses:\n address1: 12 Heather Street, Parnell, Auckland, New Zealand\n address2: 1 Queen Street, CBD, Auckland, New Zealand\n" | |
safe -- true | |
"---\nname: Fredrick Smith\nquantity: 1000000\ndate: '2017-08-11 11:17:00 -0400'\naddresses:\n address1: 12 Heather Street, Parnell, Auckland, New Zealand\n address2: 1 Queen Street, CBD, Auckland, New Zealand\n" | |
----- | |
- symbol and date thrown in there | |
marshal -- true | |
"\x04\b{\t:\tnameI\"\x13Fredrick Smith\x06:\x06ET:\rquantityi\x03@B\x0F:\tdateIu:\tTime\ro]\x1D\x80\xF5\x00$U\a:\voffseti\xFE\xC0\xC7:\tzoneI\"\bEDT\x06;\x06F:\x0Eaddresses{\a:\raddress1I\"612 Heather Street, Parnell, Auckland, New Zealand\x06;\x06T:\raddress2I\"/1 Queen Street, CBD, Auckland, New Zealand\x06;\x06T" | |
bson -- false | |
"\xC3\x00\x00\x00\x02name\x00\x0F\x00\x00\x00Fredrick Smith\x00\x10quantity\x00@B\x0F\x00\tdate\x00\xB6\xA6\xE2\xD1]\x01\x00\x00\x03addresses\x00~\x00\x00\x00\x02address1\x002\x00\x00\x0012 Heather Street, Parnell, Auckland, New Zealand\x00\x02address2\x00+\x00\x00\x001 Queen Street, CBD, Auckland, New Zealand\x00\x00\x00" | |
msgpack -- ERROR | |
json -- false | |
"{\"name\":\"Fredrick Smith\",\"quantity\":1000000,\"date\":\"2017-08-11 11:21:18 -0400\",\"addresses\":{\"address1\":\"12 Heather Street, Parnell, Auckland, New Zealand\",\"address2\":\"1 Queen Street, CBD, Auckland, New Zealand\"}}" | |
yajl -- false | |
"{\"name\":\"Fredrick Smith\",\"quantity\":1000000,\"date\":\"2017-08-11 11:21:18 -0400\",\"addresses\":{\"address1\":\"12 Heather Street, Parnell, Auckland, New Zealand\",\"address2\":\"1 Queen Street, CBD, Auckland, New Zealand\"}}" | |
oj -- true | |
"{\":name\":\"Fredrick Smith\",\":quantity\":1000000,\":date\":{\"^t\":1502464878.262389000},\":addresses\":{\":address1\":\"12 Heather Street, Parnell, Auckland, New Zealand\",\":address2\":\"1 Queen Street, CBD, Auckland, New Zealand\"}}" | |
yaml -- true | |
"---\n:name: Fredrick Smith\n:quantity: 1000000\n:date: 2017-08-11 11:21:18.262389000 -04:00\n:addresses:\n :address1: 12 Heather Street, Parnell, Auckland, New Zealand\n :address2: 1 Queen Street, CBD, Auckland, New Zealand\n" | |
psych -- true | |
"---\n:name: Fredrick Smith\n:quantity: 1000000\n:date: 2017-08-11 11:21:18.262389000 -04:00\n:addresses:\n :address1: 12 Heather Street, Parnell, Auckland, New Zealand\n :address2: 1 Queen Street, CBD, Auckland, New Zealand\n" | |
safe -- ERROR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# gem install bson | |
# gem install bson_ext | |
# gem install yajl-ruby | |
# gem install json | |
# gem install msgpack | |
# gem install oj | |
# gem install psych | |
# gem install benchmark-ips | |
require 'benchmark/ips' | |
require 'rubygems' | |
require 'benchmark' | |
require 'yaml' # ruby yaml -- handles dates | |
require 'bson' # binary json | |
require 'json' # ruby json | |
require 'yajl' # json | |
require 'msgpack' # binary serializer | |
require 'oj' # json -- handles dates | |
require 'psych' # yaml -- handles dates | |
require 'optparse' | |
binary = false | |
mode = :bmbm | |
OptionParser.new do |opt| | |
opt.on('-b', '--binary', "binary data") { |v| binary = v} | |
opt.on('-i', '--ips', "ips") { mode = :ips } | |
opt.parse!(ARGV) | |
end | |
METHODS = { | |
:marshal => { :verbose => "ruby marshal", :encoder => -> (msg) { Marshal.dump(msg) }, :decoder => -> (str) { Marshal.load(str) } }, | |
:bson => { :verbose => "binary json", :encoder => -> (msg) { msg.to_bson }, :decoder => -> (str) { Hash.from_bson(str) } }, | |
:msgpack => { :verbose => "MessagePack", :encoder => -> (msg) { MessagePack.pack(msg) }, :decoder => -> (str) { MessagePack.unpack(str) } }, | |
:yaml => { :verbose => "ruby yaml", :encoder => -> (msg) { msg.to_yaml}, :decoder => -> (str) { YAML.load(str) } }, | |
:safe => { :verbose => "ruby safe", :encoder => -> (msg) { msg.to_yaml}, :decoder => -> (str) { YAML.safe_load(str) } }, | |
:psych => { :verbose => "Yaml Psych", :encoder => -> (msg) { Psych.dump(msg) }, :decoder => -> (str) { Psych.load(str) } }, | |
:json => { :verbose => "ruby json", :encoder => -> (msg) { JSON.generate(msg) }, :decoder => -> (str) { JSON.parse(str) } }, | |
:yajl => { :verbose => "Json yajl", :encoder => -> (msg) { Yajl::Encoder.encode(msg) }, :decoder => -> (str) { Yajl::Parser.parse(str) } }, | |
:oj => { :verbose => "Json oj", :encoder => -> (msg) { Oj.dump(msg) }, :decoder => -> (str) { Oj.load(str) } }, | |
} | |
SAMPLES = 5_000 | |
obj = if binary | |
{ | |
:name => "Fredrick Smith", | |
:quantity => 1_000_000, | |
:date => Time.now, | |
:addresses => { | |
:address1 => "12 Heather Street, Parnell, Auckland, New Zealand", | |
:address2 => "1 Queen Street, CBD, Auckland, New Zealand" | |
} | |
} | |
else | |
{ | |
"name" => "Fredrick Smith", | |
"quantity" => 1_000_000, | |
"date" => Time.now.to_s, | |
"addresses" => { | |
"address1" => "12 Heather Street, Parnell, Auckland, New Zealand", | |
"address2" => "1 Queen Street, CBD, Auckland, New Zealand" | |
} | |
} | |
end | |
Benchmark.send(mode) do |r| | |
METHODS.each do |method, options| | |
begin | |
encoder = options[:encoder] | |
decoder = options[:decoder] | |
same = (obj == decoder.call(encoder.call(obj))) | |
# puts(encoder.call(obj).to_s.inspect) | |
r.report("#{options[:verbose]} (#{same})") do | |
SAMPLES.times do | |
decoder.call(encoder.call(obj)) | |
end | |
end | |
rescue | |
puts "#{method} -- ERROR" | |
end | |
end | |
r.compare! if mode == :ips | |
end | |
# Results | |
# ------- | |
# user system total real | |
# marshal 0.070000 0.000000 0.070000 ( 0.068565) | |
# bson 0.050000 0.000000 0.050000 ( 0.049747) | |
# msgpack 0.030000 0.000000 0.030000 ( 0.023521) | |
# json 0.060000 0.000000 0.060000 ( 0.061108) | |
# yajl 0.050000 0.000000 0.050000 ( 0.051075) | |
# oj 0.020000 0.000000 0.020000 ( 0.022084) | |
# yaml 2.660000 0.030000 2.690000 ( 2.691348) | |
# psych 2.640000 0.030000 2.670000 ( 2.665381) | |
# safe 2.680000 0.030000 2.710000 ( 2.715144) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
my results against ruby 2.3.3, from fastest -> slowest