Skip to content

Instantly share code, notes, and snippets.

@danielnc
Forked from eirc/.rvmrc
Last active February 23, 2024 08:33
Show Gist options
  • Save danielnc/3901381 to your computer and use it in GitHub Desktop.
Save danielnc/3901381 to your computer and use it in GitHub Desktop.
Ruby-based Benchmark of MessagePack vs. JSON vs. Yajl vs. Protobuffers vs. MultiJson vs. Marshal vs. YAML vs. BSON
# encoding: utf-8
require 'rubygems'
require 'bundler'
require 'bench_press'
require 'multi_json'
require 'json'
require 'yajl'
require 'msgpack'
require './repository.pb'
require 'yaml'
require 'bson'
require 'oj'
extend BenchPress
reps 10_000
data = {
"repository" => {
"watchers" => 173,
"has_wiki" => true,
"url" => "https://github.com/flori/json",
"open_issues" => 21,
"homepage" => "http://flori.github.com/json",
"has_issues" => true,
"forks" => 35,
"fork" => false,
"language" => "Ruby",
"integrate_branch" => "master",
"created_at" => "2009/08/24 15:21:39 -0700",
"master_branch" => "master",
"size" => 572,
"private" => false,
"name" => "json",
"owner" => "flori",
"has_downloads" => true,
"pushed_at" => "2011/07/08 07:34:34 -0700",
"description" => "JSON implementation for Ruby"
}
}
json = Yajl::Encoder.encode(data)
msgpack = MessagePack.pack(data)
protobuffer = Repository.new(data['repository'])
yaml = YAML.dump(data)
marshal = Marshal.dump(data)
bson = data.to_bson
MultiJson.engine = :json_gem
measure "MultiJson.decode (json_gem)" do
MultiJson.decode(json)
end
MultiJson.engine = :json_pure
measure "MultiJson.decode (json_pure)" do
MultiJson.decode(json)
end
MultiJson.engine = :ok_json
measure "MultiJson.decode (ok_json)" do
MultiJson.decode(json)
end
MultiJson.engine = :yajl
measure "MultiJson.decode (yajl)" do
MultiJson.decode(json)
end
MultiJson.engine = :oj
measure "MultiJson.decode (oj)" do
MultiJson.decode(json)
end
measure "JSON.parse" do
JSON.parse(json)
end
measure "Yajl::Parser.parse" do
Yajl::Parser.parse(json)
end
measure "Oj.load" do
Oj.load(json)
end
measure "MessagePack.unpack" do
MessagePack.unpack(msgpack)
end
measure "Protobuffer.parse" do
Repository.parse(protobuffer.to_s)
end
measure "YAML.load" do
YAML.load(yaml)
end
measure "Marshal.load" do
Marshal.load(marshal)
end
measure "BSON.from_bson" do
Hash.from_bson(bson)
bson.rewind!
end
Decode
======
Date: June 03, 2020
System Information
------------------
Operating System: macOS 10.15.1 (19B88)
CPU: Intel(R) Core(TM) i7-6920HQ CPU @ 2.90GHz
Processor Count: 4
Memory: 16.00 GiB
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
"MessagePack.unpack" is up to 96% faster over 10,000 repetitions
----------------------------------------------------------------
MessagePack.unpack 0.09227399993687868 secs Fastest
Oj.load 0.10587099986150861 secs 12% Slower
BSON.from_bson 0.10636000009253621 secs 13% Slower
Marshal.load 0.1287609999999404 secs 28% Slower
MultiJson.decode (yajl) 0.13616500003263354 secs 32% Slower
MultiJson.decode (oj) 0.13731199991889298 secs 32% Slower
MultiJson.decode (ok_json) 0.13797500007785857 secs 33% Slower
MultiJson.decode (json_gem) 0.14256000006571412 secs 35% Slower
MultiJson.decode (json_pure) 0.14269199990667403 secs 35% Slower
Yajl::Parser.parse 0.16816399991512299 secs 45% Slower
JSON.parse 0.9026649999432266 secs 89% Slower
Protobuffer.parse 1.3191080000251532 secs 93% Slower
YAML.load 2.7210160000249743 secs 96% Slower
# encoding: utf-8
require 'rubygems'
require 'bundler'
require 'bench_press'
require 'multi_json'
require 'json'
require 'yajl'
require 'msgpack'
require './repository.pb'
require 'yaml'
require 'bson'
require 'oj'
extend BenchPress
reps 10_000
data = {
"repository" => {
"watchers" => 173,
"has_wiki" => true,
"url" => "https://github.com/flori/json",
"open_issues" => 21,
"homepage" => "http://flori.github.com/json",
"has_issues" => true,
"forks" => 35,
"fork" => false,
"language" => "Ruby",
"integrate_branch" => "master",
"created_at" => "2009/08/24 15:21:39 -0700",
"master_branch" => "master",
"size" => 572,
"private" => false,
"name" => "json",
"owner" => "flori",
"has_downloads" => true,
"pushed_at" => "2011/07/08 07:34:34 -0700",
"description" => "JSON implementation for Ruby"
}
}
# MultiJson json_gem
MultiJson.engine = :json_gem
measure "MultiJson.encode (json_gem)" do
MultiJson.encode(data)
end
# MultiJson json_pure
MultiJson.engine = :json_pure
measure "MultiJson.encode (json_pure)" do
MultiJson.encode(data)
end
# MultiJson ok_json
MultiJson.engine = :ok_json
measure "MultiJson.encode (ok_json)" do
MultiJson.encode(data)
end
# MultiJson yajl
MultiJson.engine = :yajl
measure "MultiJson.encode (yajl)" do
MultiJson.encode(data)
end
# MultiJson Oj
MultiJson.engine = :oj
measure "MultiJson.encode (oj)" do
MultiJson.encode(data)
end
# JSON
measure "JSON.generate" do
JSON.generate(data)
end
# Yajl
measure "Yajl::Encoder.encode" do
Yajl::Encoder.encode(data)
end
# Oj
measure "Oj.dump" do
Oj.dump(data)
end
# MessagePack
measure "MessagePack.pack" do
MessagePack.pack(data)
end
# ProtocolBuffers
measure "Protobuffer.new" do
Repository.new(data['repository'])
end
# YAML
measure "YAML.dump" do
YAML.dump(data)
end
# Marshal
measure "Marshal.dump" do
Marshal.dump(data)
end
measure "BSON.serialize" do
data.to_bson
end
Encode
======
Date: June 03, 2020
System Information
------------------
Operating System: macOS 10.15.1 (19B88)
CPU: Intel(R) Core(TM) i7-6920HQ CPU @ 2.90GHz
Processor Count: 4
Memory: 16.00 GiB
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
"MessagePack.pack" is up to 99% faster over 10,000 repetitions
--------------------------------------------------------------
MessagePack.pack 0.019831999903544784 secs Fastest
Oj.dump 0.027868999866768718 secs 28% Slower
MultiJson.encode (json_gem) 0.05251700012013316 secs 62% Slower
MultiJson.encode (yajl) 0.053930999943986535 secs 63% Slower
MultiJson.encode (json_pure) 0.05439399997703731 secs 63% Slower
MultiJson.encode (oj) 0.05448000016622245 secs 63% Slower
MultiJson.encode (ok_json) 0.056490999879315495 secs 64% Slower
BSON.serialize 0.072169000050053 secs 72% Slower
Marshal.dump 0.1444699999410659 secs 86% Slower
Yajl::Encoder.encode 0.1449460000731051 secs 86% Slower
Protobuffer.new 0.2053960000630468 secs 90% Slower
JSON.generate 0.576314999954775 secs 96% Slower
YAML.dump 4.590747999958694 secs 99% Slower
source :rubygems
gem 'bench_press'
gem 'multi_json'
gem 'json'
gem 'yajl-ruby'
gem 'msgpack'
gem 'ruby-protocol-buffers'
gem 'bson'
gem 'bson_ext'
gem 'oj'
GEM
remote: http://rubygems.org/
specs:
activesupport (6.0.3.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
bench_press (0.3.1)
activesupport (>= 2.3.5)
facter (>= 1.5.7)
httparty (>= 0.6.1)
jeweler (>= 1.4.0)
bson (4.9.0)
bson_ext (1.5.1)
builder (3.2.4)
concurrent-ruby (1.1.6)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
facter (4.0.25)
hocon (~> 1.3)
thor (>= 1.0.1, < 2.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
git (1.7.0)
rchardet (~> 1.8)
github_api (0.11.3)
addressable (~> 2.3)
descendants_tracker (~> 0.0.1)
faraday (~> 0.8, < 0.10)
hashie (>= 1.2)
multi_json (>= 1.7.5, < 2.0)
nokogiri (~> 1.6.0)
oauth2
hashie (4.1.0)
highline (2.0.3)
hocon (1.3.1)
httparty (0.18.0)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (1.8.2)
concurrent-ruby (~> 1.0)
jeweler (2.3.5)
builder
bundler (>= 1.0)
git (>= 1.2.5)
github_api (~> 0.11.0)
highline (>= 1.6.15)
nokogiri (>= 1.5.10)
psych (~> 2.2)
rake
rdoc
semver2
json (2.3.0)
jwt (2.2.1)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2020.0512)
mini_portile2 (2.1.0)
minitest (5.14.1)
msgpack (1.3.3)
multi_json (1.14.1)
multi_xml (0.6.0)
multipart-post (2.1.1)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
oauth2 (1.4.4)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
oj (3.10.6)
psych (2.2.4)
public_suffix (4.0.5)
rack (2.2.2)
rake (13.0.1)
rchardet (1.8.0)
rdoc (6.2.1)
ruby-protocol-buffers (1.6.1)
semver2 (3.4.2)
thor (1.0.1)
thread_safe (0.3.6)
tzinfo (1.2.7)
thread_safe (~> 0.1)
yajl-ruby (1.4.1)
zeitwerk (2.3.0)
PLATFORMS
ruby
DEPENDENCIES
bench_press
bson
bson_ext
json
msgpack
multi_json
oj
ruby-protocol-buffers
yajl-ruby
BUNDLED WITH
1.16.3
#!/usr/bin/env ruby
# Generated by the protocol buffer compiler. DO NOT EDIT!
require 'protocol_buffers'
# forward declarations
class Repository < ::ProtocolBuffers::Message; end
class Repository < ::ProtocolBuffers::Message
optional :uint32, :watchers, 1
optional :bool, :has_wiki, 2
optional :string, :url, 3
optional :uint32, :open_issues, 4
optional :string, :homepage, 5
optional :bool, :has_issues, 6
optional :uint32, :forks, 7
optional :bool, :fork, 8
optional :string, :language, 9
optional :string, :integrate_branch, 10
optional :string, :created_at, 11
optional :string, :master_branch, 12
optional :uint32, :size, 13
optional :bool, :private, 14
optional :string, :name, 15
optional :string, :owner, 16
optional :bool, :has_downloads, 17
optional :string, :pushed_at, 18
optional :string, :description, 19
gen_methods! # new fields ignored after this point
end
message repository {
optional uint32 watchers = 1;
optional bool has_wiki = 2;
optional string url = 3;
optional uint32 open_issues = 4;
optional string homepage = 5;
optional bool has_issues = 6;
optional uint32 forks = 7;
optional bool fork = 8;
optional string language = 9;
optional string integrate_branch = 10;
optional string created_at = 11;
optional string master_branch = 12;
optional uint32 size = 13;
optional bool private = 14;
optional string name = 15;
optional string owner = 16;
optional bool has_downloads = 17;
optional string pushed_at = 18;
optional string description = 19;
}
# encoding: utf-8
require 'rubygems'
require 'bundler'
require 'bench_press'
require 'multi_json'
require 'json'
require 'yajl'
require 'msgpack'
require './repository.pb'
require 'yaml'
require 'bson'
data = {
"repository" => {
"watchers" => 173,
"has_wiki" => true,
"url" => "https://github.com/flori/json",
"open_issues" => 21,
"homepage" => "http://flori.github.com/json",
"has_issues" => true,
"forks" => 35,
"fork" => false,
"language" => "Ruby",
"integrate_branch" => "master",
"created_at" => "2009/08/24 15:21:39 -0700",
"master_branch" => "master",
"size" => 572,
"private" => false,
"name" => "json",
"owner" => "flori",
"has_downloads" => true,
"pushed_at" => "2011/07/08 07:34:34 -0700",
"description" => "JSON implementation for Ruby"
}
}
json = Yajl::Encoder.encode(data)
msgpack = MessagePack.pack(data)
protobuffer = Repository.new(data['repository'])
yaml = YAML.dump(data)
marshal = Marshal.dump(data)
bson = data.to_bson
puts 'Message Sizes:'
puts "JSON: #{json.to_s.bytesize} bytes"
puts "msgpack: #{msgpack.to_s.bytesize} bytes"
puts "protobuffer: #{protobuffer.to_s.bytesize} bytes"
puts "yaml: #{yaml.to_s.bytesize} bytes"
puts "bson: #{bson.to_s.bytesize} bytes"
Message Sizes:
JSON: 461 bytes
msgpack: 373 bytes
protobuffer: 204 bytes
yaml: 460 bytes
bson: 448 bytes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment