module MRuby BENCHMARK_REPEAT = 4 end $dat_files = [] def bm_files Dir.glob("#{MRUBY_ROOT}/benchmark/bm_*.rb").sort end def build_config_name path = MRuby::Build.mruby_config_path File.basename(path, '.rb').gsub('build_config_', '') end def plot_file File.join(MRUBY_ROOT, 'benchmark', "#{build_config_name}.png") end def plot raise "no build target to benchmark against" if $dat_files.empty? opts_file = "#{MRUBY_ROOT}/benchmark/plot.gpl" opts = File.read(opts_file).each_line.to_a.map(&:strip).join(';') dat_files = $dat_files.group_by {|f| File.dirname(f).split(File::SEPARATOR)[-1]} opts += ";set output '#{plot_file}'" opts += ';plot ' opts += dat_files.keys.map do |data_file| %Q['-' u 2:3:4:xtic(1) w hist title columnheader(1)] end.join(',') opts += ';' cmd = %Q{gnuplot -p -e "#{opts}"} IO.popen(cmd, 'w') do |p| dat_files.each do |target_name, bm_files| p.puts target_name.gsub('_', '-') bm_files.each do |bm_file| p.write File.read(bm_file) end p.puts "e" end end puts "Benchmark results output to #{plot_file}" end MRuby.each_target do |target| next if !target.benchmark_enabled? || target.internal? mruby_bin = "#{target.build_dir}/bin/mruby" bm_files.each do |bm_file| bm_name = File.basename bm_file, ".rb" dat_dir = File.join('benchmark', build_config_name, target.name) dat_file = File.join(dat_dir, "#{bm_name}.dat") $dat_files << dat_file directory dat_dir file dat_file => [bm_file, dat_dir, mruby_bin] do |task| print bm_name puts "..." data = (0...MRuby::BENCHMARK_REPEAT).map do |n| str = %x{(time -p #{mruby_bin} #{bm_file}) 2>&1 >/dev/null} str.scan(/\d+\.\d+$/).map(&:to_f) # [real, user, sys] end File.open(task.name, "w") do |f| data = data.map {|_,r,s| (r + s) / 2.0} min = data.min max = data.max avg = data.inject(&:+) / data.size f.puts "#{bm_name.gsub('_', '-')} #{avg} #{min} #{max}" end end end end file plot_file => $dat_files do plot end desc "run benchmark tests" task :benchmark => plot_file do plot end