require 'benchmark'
require 'active_record'
socket_file = [
"/opt/local/var/run/mysql5/mysqld.sock",
"tmp/mysqld.sock",
"tmp/mysql.sock"
].find { |path| File.exists?(path) }
configuration_options = {
:adapter => 'mysql',
:username => 'root',
:password => '',
:database => 'data_mapper_1'
}
configuration_options[:socket] = socket_file unless socket_file.nil?
ActiveRecord::Base.establish_connection(configuration_options)
ActiveRecord::Base.find_by_sql('SELECT 1')
class ARAnimal < ActiveRecord::Base #:nodoc:
set_table_name 'animals'
end
class ARPerson < ActiveRecord::Base #:nodoc:
set_table_name 'people'
end
require 'lib/data_mapper'
DataMapper::Database.setup(configuration_options)
class DMAnimal < DataMapper::Base #:nodoc:
set_table_name 'animals'
property :name, :string
property :notes, :text
end
class DMPerson < DataMapper::Base #:nodoc:
set_table_name 'people'
property :name, :string
property :age, :integer
property :occupation, :string
property :type, :class
property :notes, :text
property :date_of_birth, :date
embed :address, :prefix => true do
property :street, :string
property :city, :string
property :state, :string, :size => 2
property :zip_code, :string, :size => 10
def city_state_zip_code
"#{city}, #{state} #{zip_code}"
end
def to_s
"#{street}\n#{city_state_zip_code}"
end
end
end
class Exhibit < DataMapper::Base #:nodoc:
property :name, :string
belongs_to :zoo
end
class Zoo < DataMapper::Base #:nodoc:
property :name, :string
property :notes, :text
has_many :exhibits
end
class ARZoo < ActiveRecord::Base #:nodoc:
set_table_name 'zoos'
has_many :exhibits, :class_name => 'ARExhibit', :foreign_key => 'zoo_id'
end
class ARExhibit < ActiveRecord::Base #:nodoc:
set_table_name 'exhibits'
belongs_to :zoo, :class_name => 'ARZoo', :foreign_key => 'zoo_id'
end
N = (ENV['N'] || 1000).to_i
# 4.times do
# [DMAnimal, Zoo, Exhibit].each do |klass|
# klass.all.each do |instance|
# klass.create(instance.attributes.reject { |k,v| k == :id })
# end
# end
# end
Benchmark::send(ENV['BM'] || :bmbm, 40) do |x|
x.report('ActiveRecord:id') do
N.times { ARAnimal.find(1).name }
end
x.report('ActiveRecord:id:raw_result-set') do
connection = ARAnimal.connection
N.times do
result = connection.execute("SELECT name FROM animals WHERE id = 1")
result.each do |row|
nil
end
result.free if result.respond_to?(:free)
end
end
x.report('DataMapper:id') do
N.times { DMAnimal[1].name }
end
x.report('DataMapper:id:in-session') do
database do
N.times { DMAnimal[1].name }
end
end
x.report('DataMapper:id:raw-result-set') do
database.adapter.connection do |db|
N.times do
command = db.create_command("SELECT name FROM animals WHERE id = 1")
command.execute_reader do |reader|
reader.each { reader.current_row }
end
end
end
end
x.report('ActiveRecord:all') do
N.times { ARZoo.find(:all).each { |a| a.name } }
end
x.report('DataMapper:all') do
N.times { Zoo.all.each { |a| a.name } }
end
x.report('DataMapper:all:in-session') do
database do
N.times { Zoo.all.each { |a| a.name } }
end
end
x.report('ActiveRecord:conditions') do
N.times { ARZoo.find(:first, :conditions => ['name = ?', 'Galveston']).name }
end
x.report('DataMapper:conditions:short') do
N.times { Zoo.first(:name => 'Galveston').name }
end
x.report('DataMapper:conditions:short:in-session') do
database do
N.times { Zoo.first(:name => 'Galveston').name }
end
end
x.report('DataMapper:conditions:long') do
N.times { Zoo.find(:first, :conditions => ['name = ?', 'Galveston']).name }
end
x.report('DataMapper:conditions:long:in-session') do
database do
N.times { Zoo.find(:first, :conditions => ['name = ?', 'Galveston']).name }
end
end
people = [
['Sam', 29, 'Programmer', 'A slow text field'],
['Amy', 28, 'Business Analyst Manager', 'A slow text field'],
['Scott', 25, 'Programmer', 'A slow text field'],
['Josh', 23, 'Supervisor', 'A slow text field'],
['Bob', 40, 'Peon', 'A slow text field']
]
DMPerson.truncate!
x.report('ActiveRecord:insert') do
N.times do
people.each do |a|
ARPerson::create(:name => a[0], :age => a[1], :occupation => a[2], :notes => a[3])
end
end
end
DMPerson.truncate!
x.report('DataMapper:insert') do
N.times do
people.each do |a|
DMPerson::create(:name => a[0], :age => a[1], :occupation => a[2], :notes => a[3])
end
end
end
x.report('ActiveRecord:update') do
N.times do
bob = ARAnimal.find(:first, :conditions => ["name = ?", 'Elephant'])
bob.name
bob.notes = 'Updated by ActiveRecord'
bob.save
end
end
x.report('DataMapper:update') do
N.times do
bob = DMAnimal.first(:name => 'Elephant')
bob.name
bob.notes = 'Updated by DataMapper'
bob.save
end
end
x.report('ActiveRecord:associations:lazy') do
N.times do
zoos = ARZoo.find(:all)
zoos.each { |zoo| zoo.name; zoo.exhibits.entries }
end
end
x.report('ActiveRecord:associations:included') do
N.times do
zoos = ARZoo.find(:all, :include => [:exhibits])
zoos.each { |zoo| zoo.name; zoo.exhibits.entries }
end
end
x.report('DataMapper:associations') do
N.times do
Zoo.all.each { |zoo| zoo.name; zoo.exhibits.entries }
end
end
x.report('DataMapper:associations:in-session') do
database do
N.times do
Zoo.all.each { |zoo| zoo.name; zoo.exhibits.entries }
end
end
end
x.report('ActiveRecord:find_by_sql') do
N.times do
ARZoo.find_by_sql("SELECT * FROM zoos").each { |z| z.name }
end
end
x.report('DataMapper:find_by_sql') do
N.times do
database.query("SELECT * FROM zoos").each { |z| z.name }
end
end
x.report('DataMapper:raw-query') do
N.times do
database.adapter.connection do |db|
command = db.create_command("SELECT * FROM zoos")
command.execute_reader do |reader|
reader.each { reader.current_row }
end
end
end
end
x.report('ActiveRecord:accessors') do
person = ARPerson.find(:first)
N.times do
<<-VCARD
#{person.name} (#{person.age})
#{person.occupation}
#{person.address_street}
#{person.address_city}, #{person.address_state} #{person.address_zip_code}
#{person.notes}
VCARD
end
end
x.report('DataMapper:accessors') do
person = DMPerson.first
N.times do
<<-VCARD
#{person.name} (#{person.age})
#{person.occupation}
#{person.address}
#{person.notes}
VCARD
end
end
end