Skip to content

Instantly share code, notes, and snippets.

@gnagel
Forked from PatrickTulskie/orm_benchmark.rb
Last active December 12, 2015 05:38
Show Gist options
  • Save gnagel/4723240 to your computer and use it in GitHub Desktop.
Save gnagel/4723240 to your computer and use it in GitHub Desktop.
require 'benchmark'
require 'pp'
require 'active_record'
require 'sequel'
require 'data_mapper'
@start = Date.parse("2012-12-01")
@end = Date.parse("2012-12-31")
ActiveRecord::Base.establish_connection(adapter: 'mysql2', database: 'escobar_development', cast: false, username: 'root', password: nil, pool: 5, timeout: 5000)
class MCwAR < ActiveRecord::Base
self.table_name = 'marketing_costs'
end
Sequel.connect(adapter: 'mysql2', user: 'root', password: nil, host: 'localhost', database: 'escobar_development')
class MCwSq < Sequel::Model(:marketing_costs)
end
class MCwDM
include DataMapper::Resource
storage_names[:default] = 'marketing_costs'
property :id, Serial # An auto-increment integer key
property :ad_dimension, String
property :ad_group, String
property :ad_position, String
property :ad_type, String
property :ad_url, String
property :campaign, String
property :content, String
property :cost, Decimal
property :cost_events, Integer
property :cost_model, String
property :created_at, DateTime
property :creative_filename, String
property :date, Date
property :datetime, DateTime
property :import_id, Integer
property :impressions, Integer
property :match_type, String
property :medium, String
property :placement, String
property :source_id, Integer
property :source_name, String
property :source_type, String
property :sub_id, String
property :term, String
property :time, Time
property :timestamp, DateTime
property :tv_market, String
property :updated_at, DateTime
end
# Connect to the database
DataMapper.setup(:default, 'mysql://root@localhost/escobar_development')
# Finalize all the database models
# This will drastically improve the performance of your app
DataMapper.finalize
# By default throw an exception if a model fails validation
# Never leave home without this or your towel. -HGTTG
DataMapper::Model.raise_on_save_failure = true
###
### Pre-Populate the table with some data
###
# DataMapper.auto_migrate! # ==> Drops & Creates the table
# DataMapper.auto_upgrade! # ==> Perform any migrations on the table
# 1.upto(31) do |day|
# timestamp = Date.parse("2012-12-%02d" % day)
# 'A'.upto('Z') do |campaign|
# 0.upto(5) do |source_id|
# 0.upto(5) do |cost_events|
# 0.upto(5) do |cost|
# MCwDM.create(:campaign => campaign, :source_id => source_id, :cost_events => cost_events, :cost => cost, :timestamp => timestamp).save
# end
# end
# end
# end
# end
GC.start; GC.disable
Benchmark.bm do |x|
x.report("[%15s]" % "activerecord") do
100.times do
objs = MCwAR.select(['source_id', 'campaign', 'sum(cost)', 'sum(cost_events)']).where(date: (@start..@end)).group(['source_id', 'campaign'])
objs.each do |obj|
row_id = obj.source_id.to_s + obj.campaign.to_s
end
end
end
GC.enable; GC.start; GC.disable
x.report("[%15s]" % "sequel") do
100.times do
objs = MCwSq.select_group(:source_id, :campaign).select_append{sum(cost)}.select_append{sum(cost_events)}.where(date: (@start..@end))
objs.each do |obj|
row_id = obj.source_id.to_s + obj.campaign.to_s
end
end
end
GC.enable; GC.start; GC.disable
x.report("[%15s]" % "datamapper") do
100.times do
# Find all the rows
objs = MCwDM.aggregate(:source_id, :campaign, :cost.sum, :cost_events.count, :timestamp.gte => @start, :timestamp.lte => @end)
# Map the rows to hashes
objs.collect! { |o| { :source_id => o.shift, :campaign => o.shift, :cost_sum => o.shift, :cost_events_count => o.shift } }
# Do the down and dirty
objs.each do |obj|
row_id = obj[:source_id].to_s + obj[:campaign].to_s
end
end
end
end
@gnagel
Copy link
Author

gnagel commented Feb 6, 2013

                   user       system     total    real
[   activerecord]  0.050000   0.010000   0.060000 (  0.063170)
[         sequel]  0.050000   0.000000   0.050000 (  0.053465)
[     datamapper]  0.280000   0.020000   0.300000 (  0.312492)

@gnagel
Copy link
Author

gnagel commented Feb 6, 2013

A neat trick here is use DataMapper in your backend/scraper scripts to populate the tables,
and use Sequel or ActiveRecord in your frontend to render the data as fast as possible.

This makes the development easy. reduces migrations, and simplifies your code; at the cost of not using AR-migrations.

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