Skip to content
This repository has been archived by the owner on Jan 10, 2021. It is now read-only.

Commit

Permalink
extracted benchmarking script into whysoslow gem
Browse files Browse the repository at this point in the history
  • Loading branch information
kellyredding committed Feb 20, 2012
1 parent df014eb commit 11103a1
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 116 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ source "http://rubygems.org"
gemspec

gem 'rake', '~>0.9.2'
gem 'ruby-prof'
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ GEM
rake (0.9.2.2)
ruby-prof (0.10.8)
undies (2.1.0)
whysoslow (0.0.2)
ansi (~> 1.4)
xmlss (0.4.0)
enumeration (~> 1.3)
undies (~> 2.1)
Expand All @@ -31,3 +33,4 @@ DEPENDENCIES
osheet!
rake (~> 0.9.2)
ruby-prof
whysoslow (~> 0.0)
59 changes: 34 additions & 25 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,43 @@ Bundler::GemHelper.install_tasks

task :default => :build

desc "Run the example workbook builds."
task :run_examples do
require 'examples/trivial'
require 'examples/basic'
require 'examples/basic_with_templates'
require 'examples/formats'
require 'examples/formula'
require 'examples/styles'
end
namespace :bench do

desc "Run the bench script."
task :run do
require 'bench/bench_runner'
OsheetBenchRunner.new
end

desc "Run the profiler on 1000 rows."
task :profiler do
require 'bench/profiler_runner'
runner = OsheetProfilerRunner.new(1000)
runner.print_flat(STDOUT, :min_percent => 3)
end

desc "Run the example workbook builds."
task :examples do
require 'examples/trivial'
require 'examples/basic'
require 'examples/basic_with_templates'
require 'examples/formats'
require 'examples/formula'
require 'examples/styles'
end

desc "Run all the tests, then the example builds, then the profiler."
task :all do
Rake::Task['test'].invoke
Rake::Task['bench:run'].invoke
Rake::Task['bench:profiler'].invoke
Rake::Task['bench:examples'].invoke
end

desc "Run the profiler on 1000 rows."
task :run_profiler do
require 'bench/profiler_runner'

runner = OsheetProfilerRunner.new(1000)
runner.print_flat(STDOUT, :min_percent => 3)
end

desc "Run the bench script."
task :run_bench do
require 'bench/bench_runner'

OsheetBenchRunner.new
task :bench do
Rake::Task['bench:run'].invoke
end

desc "Run all the tests, then the example builds, then the profiler."
task :run_all do
Rake::Task['test'].invoke
Rake::Task['run_examples'].invoke
Rake::Task['run_profiler'].invoke
end
105 changes: 15 additions & 90 deletions bench/bench_runner.rb
Original file line number Diff line number Diff line change
@@ -1,91 +1,21 @@
require 'benchmark'
require 'whysoslow'
require 'stringio'
require 'ansi'

require 'osheet'

class OsheetBenchResults

attr_reader :user, :system, :total, :real
attr_accessor :label, :out, :outstream

def initialize(label)
@label = label.to_s
@user, @system, @total, @real = 0
@outstream = StringIO.new(@out = "")

@memory_usage = {
:prev => 0,
:curr => 0
}
end

def user=(value_in_secs); @user = value_in_secs.to_f * 1000; end
def system=(value_in_secs); @system = value_in_secs.to_f * 1000; end
def total=(value_in_secs); @total = value_in_secs.to_f * 1000; end
def real=(value_in_secs); @real = value_in_secs.to_f * 1000; end

def measure(&block)
Benchmark.measure(&block).to_s.strip.gsub(/[^\s|0-9|\.]/, '').split(/\s+/).tap do |values|
self.user, self.system, self.total, self.real = values
end
end

def snapshot_memory_usage
@memory_usage[:prev] = @memory_usage[:curr]
@memory_usage[:curr] = current_memory_usage
end

def to_s(meas, label)
if meas == :memory
"#{label_s(label)}: #{memory_s(@memory_usage[:curr])} MB #{"(#{memory_basis_s})"}"
else
"#{label_s(label)}: #{time_s(meas)} ms"
end
end

protected

def current_memory_usage
# capture memory usage of current process in MB
(a = ((`ps -o rss= -p #{$$}`.to_i) / 1000)) <= 0 ? 1 : a
end

def label_s(label); label.rjust(15); end
def time_s(meas); self.send(meas).to_s.rjust(10); end
def memory_s(amount)
amount.to_s.rjust(4)
end
def perc_s(perc)
(perc*100).round.abs.to_s.rjust(3)
end

def memory_basis_s
if @memory_usage[:prev] == 0
"??"
else
diff = (@memory_usage[:curr] - @memory_usage[:prev])
perc = diff.to_f / @memory_usage[:prev].to_f

if diff > 0
ANSI.red + "+#{memory_s(diff.abs)} MB, #{perc_s(perc)}%" + ANSI.reset
else
ANSI.green + "-#{memory_s(diff.abs)} MB, #{perc_s(perc)}%" + ANSI.reset
end
end
end

end

class OsheetRowsResults < OsheetBenchResults

def initialize(row_count)
@scope = self
super("#{row_count} rows")
snapshot_memory_usage
puts self.to_s(:memory, "memory @ init")
@row_count = row_count
@printer = Whysoslow::DefaultPrinter.new({
:title => "#{@row_count} rows",
:verbose => true
})
@runner = Whysoslow::Runner.new(@printer)
end

measure do
def run
@runner.run do
data_values = {
:number => 1,
:text => 'text',
Expand All @@ -94,7 +24,8 @@ def initialize(row_count)
:currency => 45.23
}

@outstream << Osheet::Workbook.new {
outstream = StringIO.new(out = "")
outstream << Osheet::Workbook.new {
title "bench"

template(:row, :header) {
Expand Down Expand Up @@ -127,18 +58,14 @@ def initialize(row_count)
row :header

10.times do |i|
(row_count / 10).times do
(@row_count / 10).times do
row :data, data_values
end
@scope.snapshot_memory_usage
puts @scope.to_s(:memory, "memory @ #{((i+1)*10).to_s.rjust(3)}%")
@runner.snapshot("#{((i+1)*10).to_s.rjust(3)}%")
end
}
}.to_data(:pp => 2)
end
snapshot_memory_usage
puts self.to_s(:memory, "memory @ end")
puts self.to_s(:real, "real exec time")
end

end
Expand All @@ -151,9 +78,7 @@ def initialize
puts "Benchmark Results:"
puts
ROWS.each do |size|
puts "#{size } rows"
puts '-'*(size.to_s.length+1+4)
OsheetRowsResults.new(size)
OsheetBenchResults.new(size).run
puts
end
puts
Expand Down
3 changes: 3 additions & 0 deletions osheet.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Gem::Specification.new do |s|

s.add_development_dependency("bundler", ["~> 1.0"])
s.add_development_dependency("assert", ["~> 0.3"])
s.add_development_dependency("whysoslow", ["~> 0.0"])
s.add_development_dependency("ruby-prof")

s.add_dependency("enumeration", ["~> 1.3"])
s.add_dependency("xmlss", ["~> 0.4"])

Expand Down

0 comments on commit 11103a1

Please sign in to comment.