Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Performance comparison of different ruby serializer methods
require './serializer_benchmarks'
hash = {
'name' => 'Fredrick Smith',
'quantity' => 1_000_000,
'addresses' => {
'address1' => '12 Heather Street, Parnell, Auckland, New Zealand',
'address2' => '1 Queen Street, CBD, Auckland, New Zealand'
}
}
run(hash)
run('string')
run(3.4)
run(nil)
run(true)
source 'https://rubygems.org'
gem 'benchmark-ips', require: 'benchmark/ips'
gem 'bson'
gem 'json'
gem 'msgpack'
gem 'oj'
gem 'yajl-ruby'
GEM
remote: https://rubygems.org/
specs:
benchmark-ips (2.7.2)
bson (4.3.0)
json (2.1.0)
msgpack (1.2.4)
oj (3.5.0)
yajl-ruby (1.3.1)
PLATFORMS
ruby
DEPENDENCIES
benchmark-ips
bson
json
msgpack
oj
yajl-ruby
BUNDLED WITH
1.16.1
require './serializer_benchmarks'
hash = {
'name' => 'Fredrick Smith',
'quantity' => 1_000_000,
'addresses' => {
'address1' => '12 Heather Street, Parnell, Auckland, New Zealand',
'address2' => '1 Queen Street, CBD, Auckland, New Zealand'
}
}
class CustomClass
attr_accessor :variable
def run(a, b)
a + b
end
def ==(other_custom_class)
self.variable == other_custom_class.variable
end
end
custom_class = CustomClass.new.tap { |instance| instance.variable = 'value' }
benches = DEFAULT_BENCHES.slice(:marshal, :oj)
run(hash, benches)
run(custom_class, benches)
run('string', benches)
run(3.4, benches)
run(3, benches)
run(nil, benches)
run(true, benches)
# Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz, 16GB DDR3 RAM
# ruby 2.5.0
# all_with_hash.rb
--> Benchmarking an object of type Hash
JSON (using oj): 68.3 i/s
MessagePack: 62.7 i/s - 1.09x slower
BSON: 54.7 i/s - 1.25x slower
Marshal: 41.4 i/s - 1.65x slower
JSON (using Yajl): 31.3 i/s - 2.18x slower
JSON (built-in ruby): 26.9 i/s - 2.54x slower
YAML: 1.2 i/s - 59.15x slower
--> Benchmarking an object of type String
JSON (using oj): 344.6 i/s
BSON: 308.3 i/s - 1.12x slower
Marshal: 151.1 i/s - 2.28x slower
MessagePack: 127.8 i/s - 2.70x slower
JSON (built-in ruby): 99.2 i/s - 3.47x slower
JSON (using Yajl): 96.9 i/s - 3.55x slower
YAML: 4.7 i/s - 74.01x slower
--> Benchmarking an object of type Float
BSON: 332.6 i/s
JSON (using oj): 204.1 i/s - 1.63x slower
Marshal: 168.1 i/s - 1.98x slower
MessagePack: 124.3 i/s - 2.68x slower
JSON (built-in ruby): 83.8 i/s - 3.97x slower
JSON (using Yajl): 80.2 i/s - 4.15x slower
YAML: 4.5 i/s - 73.27x slower
# reduced_with_different_objects.rb
--> Benchmarking an object of type Float
JSON (using oj): 198.8 i/s
Marshal: 169.1 i/s - 1.18x slower
--> Benchmarking an object of type Hash
JSON (using oj): 70.9 i/s
Marshal: 44.4 i/s - 1.60x slower
--> Benchmarking an object of type String
JSON (using oj): 368.0 i/s
Marshal: 158.3 i/s - 2.33x slower
--> Benchmarking an object of type CustomClass
JSON (using oj): 195.2 i/s
Marshal: 87.4 i/s - 2.23x slower
require 'benchmark/ips'
require 'bson'
require 'json'
require 'msgpack'
require 'oj'
require 'yajl'
require 'yaml'
SAMPLES = 5_000
DEFAULT_BENCHES = {
marshal: 'Marshal',
json: 'JSON (built-in ruby)',
yajl: 'JSON (using Yajl)',
oj: 'JSON (using oj)',
bson: 'BSON',
yaml: 'YAML',
msgpack: 'MessagePack'
}.freeze
def encode(msg, format)
case format
when :yaml
msg.to_yaml
when :marshal
Marshal.dump(msg)
when :json
JSON.generate(msg)
when :yajl
Yajl::Encoder.encode(msg)
when :oj
Oj.dump(msg)
when :bson
msg.to_bson
when :msgpack
MessagePack.pack(msg)
end
end
def decode(str, format, type)
case format
when :yaml
YAML.load(str)
when :marshal
Marshal.load(str)
when :json
JSON.parse(str)
when :yajl
Yajl::Parser.parse(str)
when :oj
Oj.load(str)
when :bson
type.from_bson(str)
when :msgpack
MessagePack.unpack(str)
end
end
def run(obj, benches = DEFAULT_BENCHES)
puts "--> Benchmarking an object of type #{obj.class}"
Benchmark.ips do |r|
benches.each do |key, title|
r.report(title) do
SAMPLES.times do
decoded_obj = decode(encode(obj, key), key, obj.class)
if decoded_obj != obj
raise <<~RAISE
Deserialized object of type #{obj.class} is not the same as before serialization / deserialization
before: #{obj.inspect}
after: #{decoded_obj.inspect}
RAISE
end
end
end
end
r.compare!
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.