module Benchcc

Constants

DEFAULT_TWEAK

How do I make this private?

VERSION
Y_FEATURES

Public Class Methods

benchmark( erb_file:, environments:, compilation_timeout:, execution_timeout:, evaluate_erb_relative_to:, features:, compiler_executable:, compiler_id:, compiler_options: ) click to toggle source
# File lib/benchcc/benchmark.rb, line 23
def benchmark(
    erb_file:, # String or Pathname
    environments:, # Array of Hash
    compilation_timeout:, # Int
    execution_timeout:, # Int
    evaluate_erb_relative_to:, # String or Pathname
    features:, # Array of Symbol
    compiler_executable:, # String
    compiler_id:, # String
    compiler_options: # Array of String
  )
  erb_file = Pathname.new(erb_file)
  progress = ProgressBar.create(format: '%p%% | %B |', total: environments.size)
  compiler = Benchcc::which(compiler_id)

  data = CSV.generate({headers: :first_row}) do |csv|
    csv << [:input_size] + features

    environments.each do |env|
      code = Renderer.new(evaluate_erb_relative_to).render(erb_file, **env)
      begin
        row = {input_size: env[:input_size]}
        Tempfile.create([erb_file.basename, '.cpp']) do |tmp|
          tmp.write(code) && tmp.close

          row.merge!(
            compiler.call(
              input_file: tmp.path,
              features: features,
              compiler_executable: compiler_executable,
              compiler_options: compiler_options,
              compilation_timeout: compilation_timeout,
              execution_timeout: execution_timeout
            )
          )
        end

      rescue CompilationError, CompilationTimeout => e
        $stderr << e
        break

      rescue ExecutionError, ExecutionTimeout => e
        $stderr << e
        break unless features.include?(:compilation_time) || features.include?(:memory_usage)

      ensure
        csv << row
        progress.increment
      end
    end
  end
  return data
ensure
  progress.finish
end
plot(title, output, curves, x_feature: :input_size, y_feature: :compilation_time, &tweak) click to toggle source

title:

The title used for the plot.

output:

The name of the file in which the plot is written.

curves:

An array of hashes of the form
  { title: <curve title>, input: <data set file> }
representing the curves to draw on the plot.
# File lib/benchcc/plot.rb, line 37
def plot(title, output, curves, x_feature: :input_size, y_feature: :compilation_time, &tweak)
  x_feature, y_feature = x_feature.to_sym, y_feature.to_sym
  raise ArgumentError if not Benchcc::Y_FEATURES.include?(y_feature)
  tweak ||= Benchcc::DEFAULT_TWEAK[y_feature]

  Gnuplot.open do |io|
    Gnuplot::Plot.new(io) do |plot|
      plot.title    title
      plot.term     'png'
      plot.output   output
      plot.data = curves.map { |curve|
        csv = CSV.table(curve[:input])
        ys = csv[y_feature]
        xs = csv[x_feature]

        # Remove trailing nils from the y-axis. nils can arise when e.g.
        # runtime execution failed but we still kept on gathering info
        # for the compilation, so the execution_time column has some
        # trailing empty values.
        ys.pop until ys.last

        # Restrict the x-axis to the number of valid y-axis values.
        xs = xs[0...ys.size]

        Gnuplot::DataSet.new([xs, ys]) { |ds|
          ds.title = curve[:title]
          ds.with = 'lines'
        }
      }
      tweak.call(plot)
    end
  end
end
which(compiler_id) click to toggle source
# File lib/benchcc/compiler.rb, line 110
def which(compiler_id)
  case compiler_id
  when 'Clang'
    return Clang.new
  else
    raise ArgumentError.new("Unsupported compiler id: #{compiler_id}")
  end
end

Private Instance Methods

benchmark( erb_file:, environments:, compilation_timeout:, execution_timeout:, evaluate_erb_relative_to:, features:, compiler_executable:, compiler_id:, compiler_options: ) click to toggle source
# File lib/benchcc/benchmark.rb, line 23
def benchmark(
    erb_file:, # String or Pathname
    environments:, # Array of Hash
    compilation_timeout:, # Int
    execution_timeout:, # Int
    evaluate_erb_relative_to:, # String or Pathname
    features:, # Array of Symbol
    compiler_executable:, # String
    compiler_id:, # String
    compiler_options: # Array of String
  )
  erb_file = Pathname.new(erb_file)
  progress = ProgressBar.create(format: '%p%% | %B |', total: environments.size)
  compiler = Benchcc::which(compiler_id)

  data = CSV.generate({headers: :first_row}) do |csv|
    csv << [:input_size] + features

    environments.each do |env|
      code = Renderer.new(evaluate_erb_relative_to).render(erb_file, **env)
      begin
        row = {input_size: env[:input_size]}
        Tempfile.create([erb_file.basename, '.cpp']) do |tmp|
          tmp.write(code) && tmp.close

          row.merge!(
            compiler.call(
              input_file: tmp.path,
              features: features,
              compiler_executable: compiler_executable,
              compiler_options: compiler_options,
              compilation_timeout: compilation_timeout,
              execution_timeout: execution_timeout
            )
          )
        end

      rescue CompilationError, CompilationTimeout => e
        $stderr << e
        break

      rescue ExecutionError, ExecutionTimeout => e
        $stderr << e
        break unless features.include?(:compilation_time) || features.include?(:memory_usage)

      ensure
        csv << row
        progress.increment
      end
    end
  end
  return data
ensure
  progress.finish
end
plot(title, output, curves, x_feature: :input_size, y_feature: :compilation_time, &tweak) click to toggle source

title:

The title used for the plot.

output:

The name of the file in which the plot is written.

curves:

An array of hashes of the form
  { title: <curve title>, input: <data set file> }
representing the curves to draw on the plot.
# File lib/benchcc/plot.rb, line 37
def plot(title, output, curves, x_feature: :input_size, y_feature: :compilation_time, &tweak)
  x_feature, y_feature = x_feature.to_sym, y_feature.to_sym
  raise ArgumentError if not Benchcc::Y_FEATURES.include?(y_feature)
  tweak ||= Benchcc::DEFAULT_TWEAK[y_feature]

  Gnuplot.open do |io|
    Gnuplot::Plot.new(io) do |plot|
      plot.title    title
      plot.term     'png'
      plot.output   output
      plot.data = curves.map { |curve|
        csv = CSV.table(curve[:input])
        ys = csv[y_feature]
        xs = csv[x_feature]

        # Remove trailing nils from the y-axis. nils can arise when e.g.
        # runtime execution failed but we still kept on gathering info
        # for the compilation, so the execution_time column has some
        # trailing empty values.
        ys.pop until ys.last

        # Restrict the x-axis to the number of valid y-axis values.
        xs = xs[0...ys.size]

        Gnuplot::DataSet.new([xs, ys]) { |ds|
          ds.title = curve[:title]
          ds.with = 'lines'
        }
      }
      tweak.call(plot)
    end
  end
end
which(compiler_id) click to toggle source
# File lib/benchcc/compiler.rb, line 110
def which(compiler_id)
  case compiler_id
  when 'Clang'
    return Clang.new
  else
    raise ArgumentError.new("Unsupported compiler id: #{compiler_id}")
  end
end