Created
November 26, 2012 06:10
-
-
Save etaque/4146802 to your computer and use it in GitHub Desktop.
Benchmark MongoDB#$inc vs Redis#hincrbyfloat
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source :rubygems | |
gem 'redis' | |
gem 'mongoid' | |
gem 'celluloid' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
production: | |
sessions: | |
default: | |
database: benchmark_gauges | |
hosts: | |
- localhost:27017 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'bundler' | |
Bundler.require | |
account_refs = (0..1000).map{|i| "%010d" % i} | |
usages = (0..9).map{|i| "usage#{i}" } | |
month = "2012-12" | |
ENV['MONGOID_ENV'] = 'production' | |
Mongoid.load!("mongoid.yml") | |
class Gauge | |
include Mongoid::Document | |
field :account_ref, type: String | |
field :month, type: String | |
field :values, type: Hash | |
index({account_ref: 1, month: 1}) | |
end | |
Gauge.create_indexes | |
class Worker | |
include Celluloid | |
def initialize(count) | |
@count = count | |
@account_refs = (0..100).map{|i| "%010d" % i} | |
@usages = (0..9).map{|i| "usage#{i}" } | |
@month = "2012-12" | |
end | |
end | |
class RedisWorker < Worker | |
def work | |
redis = Redis.new | |
@count.times do | |
key = ["fairuse", @account_refs.sample, @month].join(":") | |
redis.hincrbyfloat(key, @usages.sample, rand.round(5)) | |
end | |
true | |
end | |
end | |
class MongoDBWorker < Worker | |
def work | |
@count.times do | |
Gauge.where({account_ref: @account_refs.sample, month: @month}). | |
find_and_modify({"values" => { "usage" => {"$inc" => rand.round(5) } } }, | |
new: true, upsert: true) | |
end | |
true | |
end | |
end | |
class Runner | |
def initialize(pool_size, count) | |
@count = count | |
@pool_size = pool_size | |
@redis_pool = RedisWorker.pool(size: pool_size, args: [count]) | |
@mongodb_pool = MongoDBWorker.pool(size: pool_size, args: [count]) | |
@redis_times = [] | |
@mongodb_times = [] | |
end | |
def run | |
t = Time.now | |
@pool_size.times.map { @redis_pool.future :work }.map(&:value) | |
@redis_times << Time.now - t | |
t = Time.now | |
@pool_size.times.map { @mongodb_pool.future :work }.map(&:value) | |
@mongodb_times << Time.now - t | |
end | |
def print | |
puts "Redis: #{@redis_times.sum / @redis_times.size}" | |
puts "MongoDB: #{@mongodb_times.sum / @mongodb_times.size}" | |
end | |
end | |
pool_size, count = *ARGV | |
@runner = Runner.new(pool_size.to_i, count.to_i) | |
5.times do |i| | |
puts "Iteration #{i}" | |
@runner.run | |
end | |
@runner.print |
emilien:ruby-1.9.3 gauges/ $ ruby run.rb 10 10000
Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Redis: 19.4338594
MongoDB: 78.7857702
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
emilien:ruby-1.9.3 gauges/ $ ruby run.rb 4 1000
Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Redis: 0.6949892
MongoDB: 2.9080958
emilien:ruby-1.9.3 gauges/ $ ruby run.rb 10 1000
Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Redis: 1.5602584
MongoDB: 6.273723800000001