module B # print results in TSV format class TsvWriter COLUMNS = [:group, :id, :rounds, :rate, :mean, :max, :min, :stddev, :x] def initialize(out=$stdout) @out = out printf COLUMNS.join("\t") + "\n" end def finish(job) printf COLUMNS.map { |c| job.send(c) }.join("\t") + "\n" end private def printf(*a) @out.printf *a end end # print results as a HTML table class HtmlWriter COLUMNS = [:group, :id, :rounds, :rate, :mean, :max, :min, :stddev, :x] def register(job) @todo = (@todo||0) +1 end def initialize(out=$stdout) @out = out printf "<table>\n<tr>" COLUMNS.map { |c| printf "<th>#{c}</th>" } printf "</tr>\n" end def finish(job) @done = (@done||0) +1 printf "<tr>" COLUMNS.map { |c| printf "<td>#{job.send(c)}</td>" } printf "</tr>\n" printf "</table>\n" if @done == @todo end private def printf(*a) @out.printf *a end end # print results in human friendly tabular format # # usage hints: # * set :multiply=>1 if you want output in seconds instead of milliseconds # * increase :column_width if you see indendation issues with wide values # * increase :max_label_width if you want to see more of your labels # class ConsoleWriter C_ID, C_LABEL, C_WIDTH, C_ROUND, C_MUL = *(0..4) def initialize(opts={}) @opts = opts = { :out => $stderr, :multiply => 1000, :round => 2, :column_width => 11, :max_label_width => 20 }.merge(opts) @out = opts[:out] @max_label_width = opts[:max_label_width] @columns = [ # C_ID C_LABEL C_WIDTH C_ROUND C_MUL [:id, '', -1, nil, nil], [:rounds, 'rounds', -1, 0, 0], [:rate, 'r/s', opts[:column_width], opts[:round], 1], [:mean, 'mean', opts[:column_width], opts[:round], opts[:multiply]], [:max, 'max', opts[:column_width], opts[:round], opts[:multiply]], [:min, 'min', opts[:column_width], opts[:round], opts[:multiply]], [:stddev, "\u00b1 stddev", opts[:column_width], opts[:round], opts[:multiply]] ] end def register(job) # adjust width of first column (label) to fit longest label @columns[0][C_WIDTH] = [@columns[0][C_WIDTH], [job.id.length+2,@max_label_width].min].max # adjust width of second column (rounds) to fit widest value @columns[1][C_WIDTH] = [@columns[1][C_WIDTH], @columns[1][C_LABEL].length, job.rounds.to_s.length].max end def start(job) if @header_printed.nil? @header_printed = true # add :x column if this is a comparison if job.compare @columns << [:x, "x #{job.compare}", @opts[:column_width], @opts[:round], 1] end # print header header = '-' * (@columns.transpose[C_WIDTH].reduce(&:+) + @columns.length - 1) header[2..3+job.group.length] = " #{job.group} " printf header + "\n" @columns.each_with_index do |col, i| printf col[C_LABEL].rjust(col[C_WIDTH]) + ' ' end printf "\n" end # print job.label printf "#{job.id[0..@columns[0][C_WIDTH]-1].ljust(@columns[0][C_WIDTH])} " # print rounds printf "%#{@columns[1][C_WIDTH]}d ", job.send(:rounds) end def finish(job) @columns.each_with_index do |col, i| next if 2 > i # first two columns were already printed in start() value = job.send(col[C_ID]) * col[C_MUL] printf "%#{col[C_WIDTH]}.#{col[C_ROUND]}f ", value end printf "\n" end private def printf(*a) @opts[:out].printf *a end end end