Module: Benchmark::Perf::Execution

Defined in:
lib/benchmark/perf/execution.rb

Overview

Measure length of time the work could take on average

Class Method Summary collapse

Class Method Details

.check_greater(expected, min) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if expected value is greater than minimum

Parameters:

  • expected (Numeric)
  • min (Numeric)

Raises:

  • (ArgumentError)


121
122
123
124
125
126
# File 'lib/benchmark/perf/execution.rb', line 121

def check_greater(expected, min)
  unless expected > min
    raise ArgumentError,
          "Repeat value: #{expected} needs to be greater than #{min}"
  end
end

.run(repeat: 1, io: nil, warmup: 1, subprocess: true, &work) ⇒ Array[Float, Float]

Perform work x times

Examples:

ExecutionTime.run(repeat: 10) { ... }

Parameters:

  • repeat (Integer) (defaults to: 1)

    how many times to repeat the code measuremenets

Returns:

  • (Array[Float, Float])

    average and standard deviation



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/benchmark/perf/execution.rb', line 93

def run(repeat: 1, io: nil, warmup: 1, subprocess: true, &work)
  check_greater(repeat, 0)

  result = CPUResult.new

  run_warmup(warmup: warmup, io: io, subprocess: subprocess, &work)

  repeat.times do
    GC.start
    result << run_in_subprocess(io: io, subprocess: subprocess) do
      Clock.measure(&work)
    end
  end

  io.puts if io

  result
end

.run_in_subprocess(subprocess: true, io: nil) ⇒ Float

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Isolate run in subprocess

Examples:

iteration.run_in_subproces { ... }

Returns:

  • (Float)

    the elapsed time of the measurement



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/benchmark/perf/execution.rb', line 29

def run_in_subprocess(subprocess: true, io: nil)
  return yield unless subprocess && Process.respond_to?(:fork)
  return yield unless run_in_subprocess?

  reader, writer = IO.pipe
  reader.binmode
  writer.binmode

  pid = Process.fork do
    GC.start
    GC.disable if ENV['BENCH_DISABLE_GC']

    begin
      reader.close
      time = yield
      io.print "%9.6f" % data if io
      Marshal.dump(time, writer)
    rescue => error
      Marshal.dump(error, writer)
    ensure
      GC.enable if ENV['BENCH_DISABLE_GC']
      writer.close
      exit # allow finalizers to run
    end
  end

  writer.close unless writer.closed?
  Process.waitpid(pid)
  data = Marshal.load(reader)
  reader.close
  raise data if data.is_a?(Exception)
  data
end

.run_in_subprocess?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if measurements need to run in subprocess

Returns:

  • (Boolean)


15
16
17
# File 'lib/benchmark/perf/execution.rb', line 15

def run_in_subprocess?
  ENV["RUN_IN_SUBPROCESS"] != 'false' && Process.respond_to?(:fork)
end

.run_warmup(warmup: 1, io: nil, subprocess: true, &work) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Run warmup measurement

Parameters:

  • warmup (Numeric) (defaults to: 1)

    the warmup time



70
71
72
73
74
75
76
77
78
# File 'lib/benchmark/perf/execution.rb', line 70

def run_warmup(warmup: 1, io: nil, subprocess: true, &work)
  GC.start

  warmup.times do
    run_in_subprocess(io: io, subprocess: subprocess) do
      Clock.measure(&work)
    end
  end
end