Skip to content

Instantly share code, notes, and snippets.

@buger
Created March 18, 2012 13:42
Show Gist options
  • Save buger/2072760 to your computer and use it in GitHub Desktop.
Save buger/2072760 to your computer and use it in GitHub Desktop.
Ruby + Redis benchmark
require 'benchmark'
#require 'unprof'
require "redis"
require 'bson' # Using bson to speedup decoding
r = Random.new
$db = Redis.new
=begin
Example of generated rule:
{
"campaign_id" : 1,
"site_id" : 1,
"offer_value" : 11,
"offer_type" : "discount",
"rule_location" : [ 2, 2 ],
"rule_order_sum_start" : 40,
"rule_order_sum_end" : 60,
"rule_site_visit_count" : 6,
"rule_order_state" : 1,
"rule_product_price" : 2
},
{
"campaign_id" : 2,
"site_id" : 1,
"offer_value" : 10,
"offer_type" : "discount",
"rule_site_visit_count" : 5
}
=end
puts "filling redis with rules:",
Benchmark.measure {
10.times do |site_id| # Clients count
records = []
$db.multi do
$db.del "site:#{site_id}:rules"
10.times do |campaign_id| # each client has 10 campaigns
campaign_id = 100 * site_id + campaign_id # making camaign_id unique
300.times do |rule_id| # each campaign have 300 rules
rule_id = 1000 * campaign_id + rule_id
$db.lpush "site:#{site_id}:rules", rule_id
record = {
campaign_id: campaign_id,
site_id: site_id,
offer_value: r.rand(10..20),
offer_type: "discount"
}
has_rule = false
if r.rand(2) == 1 # insert this rule only in every third record
record[:rule_location] = [r.rand(10), r.rand(20)]
has_rule = true
end
if r.rand(2) == 1
record[:rule_order_sum_start] = r.rand(30..60)
record[:rule_order_sum_end] = r.rand(60..80)
has_rule = true
end
if r.rand(2) == 1
record[:rule_page_visit_count] = 1 + rand(10)
has_rule = true
end
if r.rand(2) == 1
record[:rule_site_visit_count] = 1 + rand(10)
has_rule = true
end
if r.rand(2) == 1
record[:rule_order_sum_start] = r.rand(30..60)
record[:rule_order_sum_end] = r.rand(60..80)
has_rule = true
end
unless has_rule # at least one rules should be
record[:rule_order_state] = rand(3)
record[:rule_page_visit_count] = 1 + rand(10)
end
$db.set "rules:#{rule_id}", BSON.serialize(record).to_s
end
end
end
end
}
cache = {}
puts Benchmark.measure {
10000.times do
user = {
location: [r.rand(10), r.rand(10)],
order_sum: r.rand(20..100),
site_visit_count: r.rand(20),
page_visit_count: r.rand(20),
order_state: r.rand(3),
site_id: r.rand(9)
}
rules = cache[user[:site_id]]
# We don't need to get data from redis all the time, cache it for a while
unless rules
rules =$db.sort "site:#{user[:site_id]}:rules",
:get => "rules:*"
rules.map! { |rule| BSON.deserialize(rule.unpack("C*")) }
cache[user[:site_id]] = rules
end
rules = rules.find_all do |rule|
pass = true
rule.keys.each do |key|
case key
when 'rule_location'
pass = false if user[:location] != rule['rule_location']
when 'rule_order_sum_start'
pass = false if rule['rule_order_sum_start'] < user[:order_sum] &&
rule['rule_order_sum_end'] > user[:order_sum]
when 'rule_page_visit_count'
pass = false if rule['rule_page_visit_count'] >= user[:page_visit_count]
when 'rule_site_visit_count'
pass = false if rule['rule_site_visit_count'] >= user[:site_visit_count]
when 'rule_order_state'
pass = false if rule['rule_order_state'] != user[:order_state]
end
end
pass
end
end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment