diff --git a/Gemfile b/Gemfile index 3cab172..1e73c14 100644 --- a/Gemfile +++ b/Gemfile @@ -4,4 +4,3 @@ source "http://rubygems.org" gemspec gem 'rake', '~>0.9.2' -gem 'ruby-prof' diff --git a/Gemfile.lock b/Gemfile.lock index 5cceff2..8c49b8a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) @@ -31,3 +33,4 @@ DEPENDENCIES osheet! rake (~> 0.9.2) ruby-prof + whysoslow (~> 0.0) diff --git a/Rakefile b/Rakefile index 731be2c..a388cbd 100644 --- a/Rakefile +++ b/Rakefile @@ -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 diff --git a/bench/bench_runner.rb b/bench/bench_runner.rb index 8ae25ba..1d83059 100644 --- a/bench/bench_runner.rb +++ b/bench/bench_runner.rb @@ -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', @@ -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) { @@ -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 @@ -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 diff --git a/osheet.gemspec b/osheet.gemspec index 2f78b87..948cde7 100644 --- a/osheet.gemspec +++ b/osheet.gemspec @@ -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"])