Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Ruby Redis benchmarks for JSON vs Marshal vs String
# http://forrst.com/posts/JSON_vs_Marshal_vs_eval_Which_is_the_fastest_fo-6Qy
require 'benchmark'
require 'json'
require 'redis'
# -----------------
puts "Initialize variables.."
# Initialize connection to Redis via unix socket
redis = Redis.new(path: '/tmp/redis.sock')
# Generate array containing nested hashes with random integers, ex: { 1931 => { 9159 => 9366 }, 'stringkey' => 'stringvalue' }
hashes = []
100000.times do |i|
hashes[i] = { Random.rand(1..100) => { Random.rand(1..100) => Random.rand(1..100) }, 'stringkey' => 'stringvalue' }
end
puts '-----------------'
puts "Benchmark converting and inserting to Redis\n\n"
# Benchmark converting all the generated hashes into Redis
Benchmark.bm(20) do |x|
# Convert to json
x.report('to_json:') { hashes.each { |h| redis.set 'hash:j', h.to_json } }
# "{\"1931\":{\"9159\":9366},\"stringkey\":\"stringvalue\"}"
# Convert to bytestream
x.report('Marshal.dump:') { hashes.each { |h| redis.set 'hash:m', Marshal.dump(h) } }
# "\x04\b{\ai\x02\x8B\a{\x06i\x02\xC7#i\x02\x96$I\"\x0Estringkey\x06:\x06EFI\"\x10stringvalue\x06;\x00F"
# Convert to string
x.report('hash.to_s:') { hashes.each { |h| redis.set 'hash:s', h } }
# "{1931=>{9159=>9366}, \"stringkey\"=>\"stringvalue\"}"
end
puts '-----------------'
puts "Retrieve from Redis to compare\n\n"
# Retrieve from Redis
rawjson = redis.get 'hash:j'
rawbytestream = redis.get 'hash:m'
rawstring = redis.get 'hash:s'
# Convert back to a hash object
json = JSON.parse(rawjson)
bytestream = Marshal.restore(rawbytestream)
string = eval(rawstring)
puts "json == bytestream: #{json == bytestream}" # FALSE
puts "string == bytestream: #{string == bytestream}" # TRUE
puts '-----------------'
puts "Benchmark retrieving from Redis and converting back to a hash\n\n"
# Benchmark converting the hash 100000 times
Benchmark.bm(20) do |x|
x.report('JSON.parse') { 100000.times { JSON.parse(redis.get 'hash:j') } }
x.report('Marshal.restore') { 100000.times { Marshal.restore(redis.get 'hash:m') } }
x.report('eval(string)') { 100000.times { eval(redis.get 'hash:s') } }
end
#
#
#
# Initialize variables..
# -----------------
# Benchmark converting and inserting to Redis
#
# user system total real
# to_json: 4.380000 1.060000 5.440000 ( 6.570592)
# Marshal.dump: 2.870000 1.030000 3.900000 ( 5.021693)
# hash.to_s: 2.890000 1.010000 3.900000 ( 4.997409)
# -----------------
# Retrieve from Redis to compare
#
# json == bytestream: false
# string == bytestream: true
# -----------------
# Benchmark retrieving from Redis and converting back to a hash
#
# user system total real
# JSON.parse 3.440000 1.070000 4.510000 ( 5.497154)
# Marshal.restore 3.130000 1.050000 4.180000 ( 5.163987)
# eval(string) 5.130000 1.140000 6.270000 ( 7.270163)
@nddeluca

This comment has been minimized.

Copy link

@nddeluca nddeluca commented Jan 23, 2014

Just the benchmark I was looking for, thanks!

@danlo

This comment has been minimized.

Copy link

@danlo danlo commented Aug 24, 2014

+1

@gtmax

This comment has been minimized.

Copy link

@gtmax gtmax commented Aug 10, 2015

+1, thanks!

@danlo

This comment has been minimized.

Copy link

@danlo danlo commented Mar 26, 2016

+1, I was looking for this too!

@sitaramshelke

This comment has been minimized.

Copy link

@sitaramshelke sitaramshelke commented May 9, 2017

+1, Thanks

@paveltyk

This comment has been minimized.

Copy link

@paveltyk paveltyk commented Jan 25, 2019

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment