Object
This is the base class of all Benchmarking Cases.
Autorun all subclasses’ instances, that is all Bullshit cases. If its autorun dsl_accessor is false or it has already run, don’t run the case.
# File lib/bullshit.rb, line 1631 def autorun_all each do |bc_class| bc_class.autorun and bc_class.run_count == 0 and bc_class.run end end
Iterate over all subclasses of class Case.
# File lib/bullshit.rb, line 1616 def each(&block) cases.each(&block) end
(Not documented)
# File lib/bullshit.rb, line 1593 def inherited(klass) klass.extend CaseExtension end
Returns a Case instance, that is used to run benchmark methods and measure their running time.
# File lib/bullshit.rb, line 1640 def initialize @clocks = [] if self.class.comparison @comparison = Comparison.new @comparison.output self.class.output end end
(Not documented)
# File lib/bullshit.rb, line 1603 def output_filename(name) path = File.expand_path(name, output_dir) output File.new(path, 'a+') end
Creates an instance of this class and run it.
# File lib/bullshit.rb, line 1784 def self.run(do_compare = true) new.run do_compare end
Run all subclasses’ instances, that is all Bullshit cases, unless they already have run.
# File lib/bullshit.rb, line 1622 def run_all each do |bc_class| bc_class.run_count == 0 and bc_class.run end end
Returns the total number of run counts run_count.
# File lib/bullshit.rb, line 1609 def run_count cases.inject(0) { |s, c| s + c.run_count } end
Return all benchmark methods of this Case instance lexicographically sorted.
# File lib/bullshit.rb, line 1655 def self.sorted_bmethods instance_methods.map { |x| x.to_s }.grep(/\Abenchmark_/).sort end
Return the CaseMethod instance for method_name or nil, if there isn’t any method of this name.
# File lib/bullshit.rb, line 1672 def [](method_name) method_name = "benchmark_#{method_name}" bmethods.find { |bm| bm.name == method_name } end
Return all benchmark methods of this Case instance in a random order.
# File lib/bullshit.rb, line 1660 def bmethods unless @bmethods @bmethods = self.class.sorted_bmethods.sort_by do rand end @bmethods.map! { |n| CaseMethod.new(n, self) } end @bmethods end
This method has to be implemented in subclasses, it should return the evaluation results of the benchmarks as a string.
# File lib/bullshit.rb, line 1841 def evaluation(clock) raise NotImplementedError, "has to be implemented in subclasses" end
Return the length of the longest_name of all these methods’ names.
# File lib/bullshit.rb, line 1678 def longest_name bmethods.empty? and return 0 bmethods.map { |x| x.short_name.size }.max end
Output after bc_method is run.
# File lib/bullshit.rb, line 1846 def post_run(bc_method) teardown_name = bc_method.teardown_name if respond_to? teardown_name $DEBUG and warn "Calling #{teardown_name}." __send__(bc_method.teardown_name) end end
Output before bc_method is run.
# File lib/bullshit.rb, line 1818 def pre_run(bc_method) setup_name = bc_method.setup_name if respond_to? setup_name $DEBUG and warn "Calling #{setup_name}." __send__(setup_name) end self.class.output.puts "#{bc_method.long_name}:" end
Setup, run all benchmark cases (warmup and the real run) and output results, run method speed comparisons, and teardown.
# File lib/bullshit.rb, line 1767 def run(do_compare = true) old_sync, self.class.output.sync = self.class.output.sync, true $DEBUG and warn "Calling setup." setup run_once do_compare and @comparison and @comparison.display self rescue => e warn "Caught #{e.class}: #{e}\n\n#{e.backtrace.map { |x| "\t#{x}\n" }}" ensure $DEBUG and warn "Calling teardown." teardown @clocks and write_files self.class.output.sync = old_sync end
Run only pre_run and post_run methods. Yield to the block, if one was given.
# File lib/bullshit.rb, line 1829 def run_method(bc_method) pre_run bc_method clock = self.class.clock.__send__(self.class.clock_method, bc_method) do __send__(bc_method.name) end bc_method.clock = clock post_run bc_method clock end
Run benchmark case once and output results.
# File lib/bullshit.rb, line 1684 def run_once self.class.run_count(self.class.run_count + 1) self.class.output.puts Time.now.strftime(' %FT%T %Z ').center(COLUMNS, '=') self.class.output.puts "Benchmarking on #{RUBY_DESCRIPTION}." self.class.output.puts self.class.message self.class.output.puts '=' * COLUMNS, '' @clocks.clear if self.class.warmup == :aggressive self.class.output.puts "Aggressively run all benchmarks for warmup first.", '' bmethods.each do |bc_method| GC.start clock = run_method bc_method self.class.output.puts evaluation(clock) GC.start end self.class.output.puts "Aggressive warmup done.", '', '=' * COLUMNS, '' end first = true bmethods.each do |bc_method| if first first = false else self.class.output.puts '-' * COLUMNS, '' end if self.class.warmup self.class.output.puts "This first run is only for warmup." GC.start clock = run_method bc_method self.class.output.puts evaluation(clock) GC.start end clock = run_method(bc_method) if self.class.truncate_data.enabled message = '' offset = clock.find_truncation_offset if clock.case.data_file slopes_file_path = clock.file_path 'slopes' message << "Writing slopes data file '#{slopes_file_path}'.\n" File.open(slopes_file_path, 'w') do |slopes_file| slopes_file.puts %w[#scatter slope] * "\t" slopes_file.puts clock.slopes.map { |s| s * "\t" } end end case offset when 0 message << "No initial data truncated.\n =>"\ " System may have been in a steady state from the beginning." when clock.repeat message << "After truncating measurements no data would have"\ " remained.\n => No steady state could be detected." else if clock.case.data_file data_file_path = clock.file_path 'untruncated' message << "Writing untruncated measurement data file '#{data_file_path}'.\n" File.open(data_file_path, 'w') do |data_file| data_file.puts clock.class.to_a * "\t" data_file.puts clock.to_a.map { |times| times * "\t" } end end remaining = clock.repeat - offset offset_percentage = 100 * offset.to_f / clock.repeat message << sprintf("Truncated initial %u measurements: "\ "%u -> %u (-%0.2f%%).\n", offset, clock.repeat, remaining, offset_percentage) clock.truncate_data(offset) end self.class.output.puts evaluation(clock), message else self.class.output.puts evaluation(clock) end @clocks << clock if @comparison @comparison.benchmark(self, bc_method.short_name, :run => false) end end @clocks end
General setup for all the benchmark methods.
# File lib/bullshit.rb, line 1855 def setup end
General teardown for all the benchmark methods.
# File lib/bullshit.rb, line 1859 def teardown end
Return the name of the benchmark case as a string.
# File lib/bullshit.rb, line 1649 def to_s self.class.benchmark_name end
Write all output files after run.
# File lib/bullshit.rb, line 1789 def write_files for clock in @clocks if clock.case.data_file data_file_path = clock.file_path self.class.output.puts "Writing measurement data file '#{data_file_path}'." File.open(data_file_path, 'w') do |data_file| data_file.puts clock.class.to_a * "\t" data_file.puts clock.to_a.map { |times| times * "\t" } end end if clock.case.histogram.enabled and clock.case.histogram.file histogram_file_path = clock.file_path 'histogram' self.class.output.puts "Writing histogram file '#{histogram_file_path}'." File.open(histogram_file_path, 'w') do |data_file| data_file.puts %w[#binleft frequency binright] * "\t" data_file.puts clock.histogram(clock.case.compare_time).to_a.map { |times| times * "\t" } end end if clock.case.autocorrelation.enabled and clock.case.autocorrelation.file ac_plot_file_path = clock.file_path 'autocorrelation' self.class.output.puts "Writing autocorrelation plot file '#{ac_plot_file_path}'." File.open(ac_plot_file_path, 'w') do |data_file| data_file.puts %w[#lag autocorrelation] * "\t" data_file.puts clock.autocorrelation_plot(clock.case.compare_time).to_a.map { |ac| ac * "\t" } end end end end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.