In Files

Parent

Files

Bullshit::Case

This is the base class of all Benchmarking Cases.

Attributes

clocks[R]

The clock instances, that were used during a run of this benchmark case.

Public Class Methods

autorun_all() click to toggle source

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
each(&block) click to toggle source

Iterate over all subclasses of class Case.

# File lib/bullshit.rb, line 1616
      def each(&block)
        cases.each(&block)
      end
inherited(klass) click to toggle source

(Not documented)

# File lib/bullshit.rb, line 1593
      def inherited(klass)
        klass.extend CaseExtension
      end
new() click to toggle source

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
output_filename(name) click to toggle source

(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
run(do_compare = true) click to toggle source

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() click to toggle source

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
run_count() click to toggle source

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
sorted_bmethods() click to toggle source

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

Public Instance Methods

[](method_name) click to toggle source

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
bmethods() click to toggle source

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
evaluation(clock) click to toggle source

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
longest_name() click to toggle source

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
post_run(bc_method) click to toggle source

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
pre_run(bc_method) click to toggle source

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
run(do_compare = true) click to toggle source

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_method(bc_method) click to toggle source

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_once() click to toggle source

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
setup() click to toggle source

General setup for all the benchmark methods.

# File lib/bullshit.rb, line 1855
    def setup
    end
teardown() click to toggle source

General teardown for all the benchmark methods.

# File lib/bullshit.rb, line 1859
    def teardown
    end
to_s() click to toggle source

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_files() click to toggle source

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.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.