Skip to content

Instantly share code, notes, and snippets.

@shilov
Created January 27, 2012 23:01
Show Gist options
  • Select an option

  • Save shilov/1691428 to your computer and use it in GitHub Desktop.

Select an option

Save shilov/1691428 to your computer and use it in GitHub Desktop.

Revisions

  1. shilov created this gist Jan 27, 2012.
    88 changes: 88 additions & 0 deletions redis_json_marshal_eval_benchmarks.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,88 @@
    # 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)