-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
356 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
source "http://rubygems.org" | ||
|
||
#gem "activerecord", "< 3" | ||
#gem "activerecord", "~> 3.1" | ||
gem "activerecord", "3.2.1" | ||
gem "rbench" | ||
gem "mysql" | ||
gem "mysql2" | ||
gem "sequel" | ||
gem "sqlite3" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
GEM | ||
remote: http://rubygems.org/ | ||
specs: | ||
activemodel (3.2.1) | ||
activesupport (= 3.2.1) | ||
builder (~> 3.0.0) | ||
activerecord (3.2.1) | ||
activemodel (= 3.2.1) | ||
activesupport (= 3.2.1) | ||
arel (~> 3.0.0) | ||
tzinfo (~> 0.3.29) | ||
activesupport (3.2.1) | ||
i18n (~> 0.6) | ||
multi_json (~> 1.0) | ||
arel (3.0.2) | ||
builder (3.0.0) | ||
i18n (0.6.0) | ||
multi_json (1.1.0) | ||
mysql (2.8.1) | ||
mysql2 (0.3.11) | ||
rbench (0.2.3) | ||
sequel (3.31.0) | ||
sqlite3 (1.3.5) | ||
tzinfo (0.3.31) | ||
|
||
PLATFORMS | ||
ruby | ||
|
||
DEPENDENCIES | ||
activerecord (= 3.2.1) | ||
mysql | ||
mysql2 | ||
rbench | ||
sequel | ||
sqlite3 |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
|
||
require 'rubygems' | ||
require 'rbench' | ||
|
||
require 'active_record' | ||
ActiveRecord::Base.establish_connection( | ||
:adapter => "sqlite3", | ||
:database => "benchmark.db" | ||
) | ||
ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS active_record_models") | ||
ActiveRecord::Base.connection.execute("CREATE TABLE active_record_models (id INTEGER UNIQUE, title STRING, text STRING)") | ||
class ActiveRecordModel < ActiveRecord::Base | ||
end | ||
# Have AR scan the table before the benchmark | ||
ActiveRecordModel.new | ||
|
||
class PlainModel | ||
attr_accessor :id, :title, :text | ||
|
||
def initialize(attrs = {}) | ||
@id, @title, @text = attrs[:id], attrs[:title], attrs[:text] | ||
end | ||
|
||
end | ||
|
||
class HashModel | ||
def initialize(attributes = {}) | ||
attrs = {} | ||
attrs.merge!(attributes) | ||
end | ||
end | ||
|
||
ATTRS = {:id => 1, :title => "Foo", :text => "Bar"} | ||
|
||
RBench.run(100_000) do | ||
|
||
column :times | ||
column :plain, :title => "Class" | ||
column :hash, :title => "Hash" | ||
column :ar, :title => "AR #{ActiveRecord::VERSION::STRING}" | ||
|
||
report ".new()" do | ||
plain do | ||
PlainModel.new | ||
end | ||
hash do | ||
Hash.new | ||
end | ||
ar do | ||
ActiveRecordModel.new | ||
end | ||
end | ||
|
||
report ".new(#{ATTRS.inspect})" do | ||
plain do | ||
PlainModel.new ATTRS | ||
end | ||
hash do | ||
Hash.new ATTRS | ||
end | ||
ar do | ||
ActiveRecordModel.new ATTRS | ||
end | ||
end | ||
|
||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
|
||
require 'benchmark' | ||
|
||
class Dummy | ||
|
||
attr_writer :setter | ||
|
||
def orig(att, value) | ||
send("#{att}=", value) if respond_to?("#{att}=") | ||
end | ||
|
||
def cache_name(att, value) | ||
method_name = "#{att}=" | ||
send(method_name, value) if respond_to?(method_name) | ||
end | ||
|
||
def symbolize_method_name(att, value) | ||
method_name = :"#{att}=" | ||
send(method_name, value) if respond_to?(method_name) | ||
end | ||
|
||
def no_iterp(att, value) | ||
method_name = (att.to_s + '=').to_sym | ||
send(method_name, value) if respond_to?(method_name) | ||
end | ||
end | ||
|
||
N = 1_000_000 | ||
@dummy = Dummy.new | ||
Benchmark.bm do |x| | ||
x.report("orig") { N.times { @dummy.orig(:setter, 1) } } | ||
x.report("cache_name") { N.times { @dummy.cache_name(:setter, 1) } } | ||
x.report("symbolize_method_name") { N.times { @dummy.symbolize_method_name(:setter, 1) } } | ||
x.report("no_iterp") { N.times { @dummy.no_iterp(:setter, 1) } } | ||
end | ||
|
||
__END__ | ||
|
||
user system total real | ||
orig 1.430000 0.000000 1.430000 ( 1.423196) | ||
cache_name 0.970000 0.000000 0.970000 ( 0.970152) | ||
symbolize_method_name 0.930000 0.000000 0.930000 ( 0.937663) | ||
no_iterp 0.830000 0.000000 0.830000 ( 0.823327) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
|
||
require "active_record" | ||
|
||
conn = { | ||
:adapter => "mysql", | ||
:database => "people_test", | ||
:socket => "/tmp/mysql.sock", | ||
:user => "root" | ||
} | ||
|
||
class ARPerson1 < ActiveRecord::Base | ||
set_table_name "people" | ||
end | ||
ARPerson1.establish_connection(conn) | ||
ARPerson1.new # Have AR scan the table before the benchmark | ||
|
||
ARPerson1.connection.execute("TRUNCATE TABLE people") | ||
|
||
if ActiveRecord::VERSION::MAJOR == 3 | ||
class ARPerson2 < ActiveRecord::Base | ||
set_table_name "people" | ||
end | ||
ARPerson2.establish_connection(conn.merge(:adapter => "mysql2")) | ||
ARPerson2.new # Have AR scan the table before the benchmark | ||
end | ||
|
||
require "sequel" | ||
|
||
conn = { | ||
:socket => "/tmp/mysql.sock", | ||
:encoding => "utf8", | ||
:user => "root", | ||
:database => "people_test" | ||
} | ||
|
||
PEOPLE_DB1 = Sequel.mysql(conn) | ||
PEOPLE_DB2 = Sequel.mysql2(conn) | ||
|
||
class SPerson1 < Sequel::Model | ||
self.set_dataset PEOPLE_DB1[:people] | ||
end | ||
SPerson1.new | ||
|
||
class SPerson2 < Sequel::Model | ||
self.set_dataset PEOPLE_DB2[:people] | ||
end | ||
SPerson2.new | ||
|
||
require "rbench" | ||
|
||
RBench.run(10_000) do | ||
column :times | ||
|
||
column :init, :title => ".new" | ||
column :insert | ||
column :select | ||
|
||
report "Hash" do | ||
init do | ||
Hash.new | ||
end | ||
end | ||
|
||
report "ActiveRecord #{ActiveRecord::VERSION::STRING} mysql" do | ||
init do | ||
ARPerson1.new | ||
end | ||
|
||
insert do | ||
ARPerson1.create!(:email => "foo#{Time.now.to_f}@email.test") | ||
end | ||
|
||
select do | ||
ARPerson1.limit(100).to_a | ||
#ARPerson1.where("created_at <= ?", Time.now).to_a | ||
end | ||
end | ||
|
||
ARPerson1.connection.execute("TRUNCATE TABLE people") | ||
|
||
if ActiveRecord::VERSION::MAJOR == 3 | ||
report "ActiveRecord #{ActiveRecord::VERSION::STRING} mysql-2" do | ||
init do | ||
ARPerson2.new | ||
end | ||
|
||
insert do | ||
ARPerson2.create!(:email => "foo#{Time.now.to_f}@email.test") | ||
end | ||
|
||
select do | ||
ARPerson2.limit(100).to_a | ||
#ARPerson2.where("created_at <= ?", Time.now).to_a | ||
end | ||
end | ||
end | ||
|
||
ARPerson1.connection.execute("TRUNCATE TABLE people") | ||
|
||
report "Sequel mysql" do | ||
init do | ||
SPerson1.new | ||
end | ||
|
||
insert do | ||
SPerson1.create(:email => "foo#{Time.now.to_f}@email.test", :created_at => Time.now) | ||
end | ||
|
||
select do | ||
SPerson1.limit(100).all | ||
#SPerson1.filter("created_at <= ?", Time.now) | ||
end | ||
end | ||
|
||
ARPerson1.connection.execute("TRUNCATE TABLE people") | ||
|
||
report "Sequel mysql-2" do | ||
init do | ||
SPerson2.new | ||
end | ||
|
||
insert do | ||
SPerson2.create(:email => "foo#{Time.now.to_f}@email.test", :created_at => Time.now) | ||
end | ||
|
||
select do | ||
SPerson2.limit(100).all | ||
#SPerson2.filter("created_at <= ?", Time.now) | ||
end | ||
end | ||
|
||
ARPerson1.connection.execute("TRUNCATE TABLE people") | ||
|
||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
require 'date' | ||
require 'time' | ||
require 'benchmark' | ||
|
||
|
||
def parse_by_split(str) | ||
day, time = str.split(':', 2) | ||
|
||
day, month, year = day.split('/') | ||
month = Date::ABBR_MONTHNAMES.index(month) | ||
|
||
hour, minute, second = time.split(':') | ||
second, offset = second.split(' ') | ||
|
||
Time.utc(year.to_i, month, day.to_i, hour.to_i, minute.to_i, second.to_f) | ||
end | ||
|
||
def parse_by_split_mktime(str) | ||
day, time = str.split(':', 2) | ||
|
||
day, month, year = day.split('/') | ||
month = Date::ABBR_MONTHNAMES.index(month) | ||
|
||
hour, minute, second = time.split(':') | ||
second, offset = second.split(' ') | ||
|
||
Time.mktime(second.to_f, minute.to_i, hour.to_i, day.to_i, month.to_i, year.to_i, nil, nil, nil, offset) | ||
end | ||
|
||
REGEX = /(\d+)\/(\w+)\/(\d+):(\d+):(\d+):(\d+) (-?\d+)/ | ||
def parse_by_regex(str) | ||
match = REGEX.match(str) | ||
month = Date::ABBR_MONTHNAMES.index(match[2]) | ||
Time.utc(match[3].to_i, month, match[1].to_i, match[4].to_i, match[5].to_i, match[6].to_f) | ||
end | ||
|
||
def parse_by_regex_mktime(str) | ||
match = REGEX.match(str) | ||
month = Date::ABBR_MONTHNAMES.index(match[2]) | ||
Time.mktime(match[6].to_i, match[5].to_i, match[4].to_i, match[1].to_i, month, match[3].to_i, nil, nil, nil, match[7]) | ||
end | ||
|
||
STRING = "01/Aug/2011:13:26:51 -0700" | ||
|
||
N = 10_000_000 | ||
Benchmark.bm(20) do |bm| | ||
bm.report("split - utc") do | ||
N.times { parse_by_split(STRING) } | ||
end | ||
|
||
bm.report("regex - utc") do | ||
N.times { parse_by_regex(STRING) } | ||
end | ||
|
||
bm.report("split - mktime") do | ||
N.times { parse_by_split_mktime(STRING) } | ||
end | ||
|
||
bm.report("regex - mktime") do | ||
N.times { parse_by_regex_mktime(STRING) } | ||
end | ||
end | ||
|
||
|