From 8bc3a147270546325458da65ae6f5e83dd260aeb Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 20 Aug 2009 21:09:59 -0700 Subject: Benchmark script via miloops' arel fork via DataMapper's AR comparison script --- activerecord/examples/.gitignore | 1 + activerecord/examples/performance.rb | 162 +++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 activerecord/examples/.gitignore create mode 100755 activerecord/examples/performance.rb diff --git a/activerecord/examples/.gitignore b/activerecord/examples/.gitignore new file mode 100644 index 0000000000..0dfc1cb7fb --- /dev/null +++ b/activerecord/examples/.gitignore @@ -0,0 +1 @@ +performance.sql diff --git a/activerecord/examples/performance.rb b/activerecord/examples/performance.rb new file mode 100755 index 0000000000..12153b490a --- /dev/null +++ b/activerecord/examples/performance.rb @@ -0,0 +1,162 @@ +#!/usr/bin/env ruby -KU + +TIMES = (ENV['N'] || 10000).to_i + +require 'rubygems' +gem 'addressable', '~>2.0' +gem 'faker', '~>0.3.1' +gem 'rbench', '~>0.2.3' +require 'addressable/uri' +require 'faker' +require 'rbench' + +__DIR__ = File.dirname(__FILE__) +$:.unshift "#{__DIR__}/../lib" +require 'active_record' + +conn = { :adapter => 'mysql', + :database => 'activerecord_unittest', + :username => 'rails', :password => '', + :encoding => 'utf8' } + +conn[:socket] = Pathname.glob(%w[ + /opt/local/var/run/mysql5/mysqld.sock + /tmp/mysqld.sock + /tmp/mysql.sock + /var/mysql/mysql.sock + /var/run/mysqld/mysqld.sock +]).find { |path| path.socket? } + +ActiveRecord::Base.establish_connection(conn) + +class User < ActiveRecord::Base + connection.create_table :users, :force => true do |t| + t.string :name, :email + t.timestamps + end + + has_many :exhibits +end + +class Exhibit < ActiveRecord::Base + connection.create_table :exhibits, :force => true do |t| + t.belongs_to :user + t.string :name + t.text :notes + t.timestamps + end + + belongs_to :user + + def look; attributes end + def feel; look; user.name end + + def self.look(exhibits) exhibits.each { |e| e.look } end + def self.feel(exhibits) exhibits.each { |e| e.feel } end +end + +sqlfile = "#{__DIR__}/performance.sql" + +if File.exists?(sqlfile) + mysql_bin = %w[mysql mysql5].select { |bin| `which #{bin}`.length > 0 } + `#{mysql_bin} -u #{conn[:username]} #{"-p#{conn[:password]}" unless conn[:password].blank?} #{conn[:database]} < #{sqlfile}` +else + puts 'Generating data...' + + # pre-compute the insert statements and fake data compilation, + # so the benchmarks below show the actual runtime for the execute + # method, minus the setup steps + + # Using the same paragraph for all exhibits because it is very slow + # to generate unique paragraphs for all exhibits. + notes = Faker::Lorem.paragraphs.join($/) + today = Date.today + + puts 'Inserting 10,000 users and exhibits...' + 10_000.times do + user = User.create( + :created_on => today, + :name => Faker::Name.name, + :email => Faker::Internet.email + ) + + Exhibit.create( + :created_on => today, + :name => Faker::Company.name, + :user => user, + :notes => notes + ) + end + + mysqldump_bin = %w[mysqldump mysqldump5].select { |bin| `which #{bin}`.length > 0 } + `#{mysqldump_bin} -u #{conn[:username]} #{"-p#{conn[:password]}" unless conn[:password].blank?} #{conn[:database]} exhibits users > #{sqlfile}` +end + +RBench.run(TIMES) do + column :times + column :ar + + report 'Model#id', (TIMES * 100).ceil do + ar_obj = Exhibit.find(1) + + ar { ar_obj.id } + end + + report 'Model.new (instantiation)' do + ar { Exhibit.new } + end + + report 'Model.new (setting attributes)' do + attrs = { :name => 'sam' } + ar { Exhibit.new(attrs) } + end + + report 'Model.first' do + ar { Exhibit.first.look } + end + + report 'Model.all limit(100)', (TIMES / 10).ceil do + ar { Exhibit.look Exhibit.all(:limit => 100) } + end + + report 'Model.all limit(100) with relationship', (TIMES / 10).ceil do + ar { Exhibit.feel Exhibit.all(:limit => 100, :include => :user) } + end + + report 'Model.all limit(10,000)', (TIMES / 1000).ceil do + ar { Exhibit.look Exhibit.all(:limit => 10000) } + end + + exhibit = { + :name => Faker::Company.name, + :notes => Faker::Lorem.paragraphs.join($/), + :created_on => Date.today + } + + report 'Model.create' do + ar { Exhibit.create(exhibit) } + end + + report 'Resource#attributes=' do + attrs_first = { :name => 'sam' } + attrs_second = { :name => 'tom' } + ar { exhibit = Exhibit.new(attrs_first); exhibit.attributes = attrs_second } + end + + report 'Resource#update' do + ar { Exhibit.first.update_attributes(:name => 'bob') } + end + + report 'Resource#destroy' do + ar { Exhibit.first.destroy } + end + + report 'Model.transaction' do + ar { Exhibit.transaction { Exhibit.new } } + end + + summary 'Total' +end + +ActiveRecord::Migration.drop_table "exhibits" +ActiveRecord::Migration.drop_table "users" -- cgit v1.2.3