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
You can’t perform that action at this time.