Permalink
Browse files

Add more benchmarks

  • Loading branch information...
paul committed Feb 22, 2012
1 parent da4dc48 commit b04ad28f86484a3de43cbd3e8ac554faee897843
Showing with 356 additions and 0 deletions.
  1. +12 −0 Gemfile
  2. +35 −0 Gemfile.lock
  3. BIN benchmark.db
  4. +67 −0 init_objects.rb
  5. +43 −0 interp.rb
  6. +135 −0 sequel_ar.rb
  7. +64 −0 split_vs_regex.rb
View
12 Gemfile
@@ -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"
+
View
@@ -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
View
Binary file not shown.
View
@@ -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
View
@@ -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)
View
@@ -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
+
View
@@ -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
+
+

0 comments on commit b04ad28

Please sign in to comment.