aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/examples/performance.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/examples/performance.rb')
-rwxr-xr-xactiverecord/examples/performance.rb162
1 files changed, 162 insertions, 0 deletions
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"