Carl Mercier's blog

me = entrepreneur + hacker;

YAML, ZAML, Marshal & JSON benchmark in Ruby

At Defensio, we recently needed to find out how slow YAML was compared to Marshal. We also wanted to know how much faster ZAML, an alternative to YAML, is.

I ran a few benchmarks under 1.8.7 MRI, 1.8.7 REE, 1.9.2 and Rubinius to see how they compare. I also benchmarked to_json to have an order of magnitude. My benchmarks consist of serializing/deserializing a relatively complex Hash (many nested levels). The YAML representation of the Hash is ~3kb.

Conclusions:

  • YAML is really slow
  • YAML is twice as fast under 1.9.2 vs 1.8.7
  • ZAML is much faster than YAML under 1.8.7, but about the same in 1.9.2
  • REE (no GC tweaks) isn’t faster in this situation
  • Rubinius is ridiculously slow
  • Psych under Ruby 1.9.2 is disappointing

Here are the results:

ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
--------------------------------------------------------------------
YAML.load: 0.7924
Marshal.load: 0.0742
to_yaml: 5.1661
ZAML.dump: 1.4574
to_json: 0.1152
Marshal.dump: 0.0845

ruby 1.8.7 (2010-04-19 patchlevel 253) [i686-darwin10.4.0], MBARI 0x6770, Ruby Enterprise Edition 2010.02
--------------------------------------------------------------------
YAML.load: 0.7976
Marshal.load: 0.0864
to_yaml: 4.9012
ZAML.dump: 1.3508
to_json: 0.0940
Marshal.dump: 0.0812

ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.5.0]
--------------------------------------------------------------------
YAML.load: 0.7079
YAML.load (Psych): 2.6055
Marshal.load: 0.0928
to_yaml: 2.1682
to_load (Psych): 2.2924
ZAML.dump: 5.0259
to_json: 0.1133
Marshal.dump: 0.0908



rubinius 1.1.1 (1.8.7 4018ebda 2010-11-16 JI) [x86_64-apple-darwin10.5.0]
--------------------------------------------------------------------
YAML.load: 2.7777
Marshal.load: 0.8560
to_yaml: 23.5828
ZAML.dump: 4.0745
to_json: 3.6620
Marshal.dump: 3.3797

If you want to benchmark on your machine, here’s the source code. Sorry, I couldn’t include the YAML string as it is confidential data.

require 'rubygems'
require 'benchmark'
require 'yaml'
require 'zaml'
require 'json'

yaml_str = <<-eos
yaml goes here
eos

h = nil
GC.start
yaml_load_time = Benchmark::realtime {
1000.times { h = YAML.load(yaml_str) }
}

GC.start
to_yaml_time = Benchmark::realtime {
1000.times { h.to_yaml }
}

begin
  YAML::ENGINE.yamler = 'psych' if RUBY_VERSION == "1.9.2"
rescue
  puts "Cannot load Psych. Is libyaml installed? Install it and recompile Ruby."
  puts "On OS X with RVM, install it with MacPorts and run:"
  puts "rvm install ruby-1.9.2 -C --with-libyaml-dir=/opt/local"
  exit 1
end

GC.start
psych_load_time = Benchmark::realtime {
  1000.times { YAML.load(yaml_str) }
}

GC.start
to_yaml_psych_time = Benchmark::realtime {
  1000.times { h.to_yaml }
}

GC.start
to_json_time = Benchmark::realtime {
1000.times { h.to_json }
}

GC.start
zaml_dump_time = Benchmark::realtime {
1000.times { ZAML.dump(h) }
}

marshaled = nil
GC.start
marshal_dump_time = Benchmark::realtime {
1000.times { marshaled = Marshal.dump(h) }
}

GC.start
marshall_load_time = Benchmark::realtime {
1000.times { h = Marshal.load(marshaled) }
}

puts `ruby -v`
puts "--------------------------------------------------------------------"
puts "YAML.load:\t\t#{'%.4f' % yaml_load_time}"
puts "YAML.load (Psych):\t#{'%.4f' % psych_load_time}" if RUBY_VERSION == "1.9.2"
puts "Marshal.load:\t\t#{'%.4f' % marshall_load_time}"
puts "to_yaml:\t\t#{'%.4f' % to_yaml_time}"
puts "to_load (Psych):\t#{'%.4f' % to_yaml_psych_time}" if RUBY_VERSION == "1.9.2"
puts "ZAML.dump:\t\t#{'%.4f' % zaml_dump_time}"
puts "to_json:\t\t#{'%.4f' % to_json_time}"
puts "Marshal.dump:\t\t#{'%.4f' % marshal_dump_time}"

Changes at IsItJRuby.com

I’ve been ridiculously busy lately. Way too busy. Too busy to sleep, to hit the gym, and definitely maintain yet another website. Unfortunately, IsItJRuby.com didn’t get the love it deserved so I started hunting for someone to take my place.

Alex Coles (@myabc) volunteered and is now the new maintainer. He already shared with me a couple good ideas for the site, which he’ll hopefully implement soon.

Thank you, Alex, and congrats!