Added back in basic benchmark support. To run:
ruby benchmark/benchmark.rb --adapter mysql --num 1000 ruby benchmark/benchmark.rb --adapter mysql --num 1000 --to-csv /tmp/results.csv ruby benchmark/benchmark.rb --adapter mysql --num 1000 --to-html /tmp/results.html
This commit is contained in:
parent
369a5e0e64
commit
5c287f1042
18 changed files with 509 additions and 22 deletions
137
benchmarks/lib/base.rb
Normal file
137
benchmarks/lib/base.rb
Normal file
|
@ -0,0 +1,137 @@
|
|||
class BenchmarkBase
|
||||
|
||||
attr_reader :results
|
||||
|
||||
# The main benchmark method dispatcher. This dispatches the benchmarks
|
||||
# to actual benchmark_xxxx methods.
|
||||
#
|
||||
# == PARAMETERS
|
||||
# * table_types - an array of table types to benchmark
|
||||
# * num - the number of record insertions to test
|
||||
def benchmark( table_types, num )
|
||||
array_of_cols_and_vals = build_array_of_cols_and_vals( num )
|
||||
table_types.each do |table_type|
|
||||
self.send( "benchmark_#{table_type}", array_of_cols_and_vals )
|
||||
end
|
||||
end
|
||||
|
||||
# Returns an OpenStruct which contains two attritues, +description+ and +tms+ after performing an
|
||||
# actual benchmark.
|
||||
#
|
||||
# == PARAMETERS
|
||||
# * description - the description of the block that is getting benchmarked
|
||||
# * blk - the block of code to benchmark
|
||||
#
|
||||
# == RETURNS
|
||||
# An OpenStruct object with the following attributes:
|
||||
# * description - the description of the benchmark ran
|
||||
# * tms - a Benchmark::Tms containing the results of the benchmark
|
||||
def bm( description, &blk )
|
||||
tms = nil
|
||||
puts "Benchmarking #{description}"
|
||||
|
||||
Benchmark.bm { |x| tms = x.report { blk.call } }
|
||||
delete_all
|
||||
failed = false
|
||||
|
||||
OpenStruct.new :description=>description, :tms=>tms, :failed=>failed
|
||||
end
|
||||
|
||||
# Given a model class (ie: Topic), and an array of columns and value sets
|
||||
# this will perform all of the benchmarks necessary for this library.
|
||||
#
|
||||
# == PARAMETERS
|
||||
# * model_clazz - the model class to benchmark (ie: Topic)
|
||||
# * array_of_cols_and_vals - an array of column identifiers and value sets
|
||||
#
|
||||
# == RETURNS
|
||||
# returns true
|
||||
def bm_model( model_clazz, array_of_cols_and_vals )
|
||||
puts
|
||||
puts "------ Benchmarking #{model_clazz.name} -------"
|
||||
|
||||
cols,vals = array_of_cols_and_vals
|
||||
num_inserts = vals.size
|
||||
|
||||
# add a new result group for this particular benchmark
|
||||
group = []
|
||||
@results << group
|
||||
|
||||
description = "#{model_clazz.name}.create (#{num_inserts} records)"
|
||||
group << bm( description ) {
|
||||
vals.each do |values|
|
||||
model_clazz.create create_hash_for_cols_and_vals( cols, values )
|
||||
end }
|
||||
|
||||
description = "#{model_clazz.name}.import(column, values) for #{num_inserts} records with validations"
|
||||
group << bm( description ) { model_clazz.import cols, vals, :validate=>true }
|
||||
|
||||
description = "#{model_clazz.name}.import(columns, values) for #{num_inserts} records without validations"
|
||||
group << bm( description ) { model_clazz.import cols, vals, :validate=>false }
|
||||
|
||||
models = []
|
||||
array_of_attrs = []
|
||||
|
||||
vals.each do |arr|
|
||||
array_of_attrs << (attrs={})
|
||||
arr.each_with_index { |value, i| attrs[cols[i]] = value }
|
||||
end
|
||||
array_of_attrs.each{ |attrs| models << model_clazz.new(attrs) }
|
||||
|
||||
description = "#{model_clazz.name}.import(models) for #{num_inserts} records with validations"
|
||||
group << bm( description ) { model_clazz.import models, :validate=>true }
|
||||
|
||||
description = "#{model_clazz.name}.import(models) for #{num_inserts} records without validations"
|
||||
group << bm( description ) { model_clazz.import models, :validate=>false }
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Returns a two element array composing of an array of columns and an array of
|
||||
# value sets given the passed +num+.
|
||||
#
|
||||
# === What is a value set?
|
||||
# A value set is an array of arrays. Each child array represents an array of value sets
|
||||
# for a given row of data.
|
||||
#
|
||||
# For example, say we wanted to represent an insertion of two records:
|
||||
# column_names = [ 'id', 'name', 'description' ]
|
||||
# record1 = [ 1, 'John Doe', 'A plumber' ]
|
||||
# record2 = [ 2, 'John Smith', 'A painter' ]
|
||||
# value_set [ record1, record2 ]
|
||||
#
|
||||
# == PARAMETER
|
||||
# * num - the number of records to create
|
||||
def build_array_of_cols_and_vals( num )
|
||||
cols = [ :my_name, :description ]
|
||||
value_sets = []
|
||||
num.times { |i| value_sets << [ "My Name #{i}", "My Description #{i}" ] }
|
||||
[ cols, value_sets ]
|
||||
end
|
||||
|
||||
# Returns a hash of column identifier to value mappings giving the passed in
|
||||
# value array.
|
||||
#
|
||||
# Example:
|
||||
# cols = [ 'id', 'name', 'description' ]
|
||||
# values = [ 1, 'John Doe', 'A plumber' ]
|
||||
# hsh = create_hash_for_cols_and_vals( cols, values )
|
||||
# # hsh => { 'id'=>1, 'name'=>'John Doe', 'description'=>'A plumber' }
|
||||
def create_hash_for_cols_and_vals( cols, vals )
|
||||
h = {}
|
||||
cols.zip( vals ){ |col,val| h[col] = val }
|
||||
h
|
||||
end
|
||||
|
||||
# Deletes all records from all ActiveRecord subclasses
|
||||
def delete_all
|
||||
ActiveRecord::Base.send( :subclasses ).each do |subclass|
|
||||
subclass.delete_all if subclass.respond_to? :delete_all
|
||||
end
|
||||
end
|
||||
|
||||
def initialize # :nodoc:
|
||||
@results = []
|
||||
end
|
||||
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue