class Benchin::Wrap

Benchmark tool for high-level nested measurement. Check out {Report#to_h} for an example of the report structure.

It's designed to use when:

By using this information you can discover which block of slow code is the slowest one.

Measurement uses WALL time.

One of the most common possible examples of usage is to investigate slow requests in legacy and big codebases. In this case more classic instruments like stack profiling can be too focused on particular methods instead of logic chunks in your code.

It can be inconvenient to 'drill' {Wrap} instance to all the places where we have to wrap some code. To address this issue we have helper {Benchin.wrap} which uses global {Wrap} instance.

@example Measure request timings in controller

class SomeDirtyController < SomeWebFramework::Controller
  def create(params)
    @bench = Benchin::Wrap.new('CREATE REQUEST')

    data = @bench.call('Create Operation') do
      do_create(params)
    end

    @bench.call('Rendering') do
      render data
    end

    File.write('report.txt', @bench.to_s)
  end

  private

  def do_create(params)
    do_something(params)
    @bench.call('Event Logging') do
      log_events
    end
  end
end
# Report saved to a file will look like:
#
# CREATE REQUEST ->
# |   time(all):       22.0
# |   Create Operation ->
# |   |   calls:              1
# |   |   time(all):       15.0
# |   |   time(self):       5.0
# |   |   time(childs):    10.0
# |   |   Event Logging ->
# |   |   |   calls:              1
# |   |   |   time(all):       10.0
# |   |   |   time(self):      10.0
# |   |   |   time(childs):     0.0
# |   Rendering ->
# |   |   calls:              1
# |   |   time(all):        7.0
# |   |   time(self):       7.0
# |   |   time(childs):     0.0

Attributes

report[R]

@return [Report] collected measurement data.

Public Class Methods

new(name) click to toggle source

@param name [String] report name

# File lib/benchin/wrap.rb, line 76
def initialize(name)
  @name = name

  @report = Report.new(@name)
  @current_path = []
end

Public Instance Methods

call(name) { || ... } click to toggle source

Wraps code block with WALL time measurement and returns the block result.

Can be used in a nested way.

@example Simple measurement

wrap = Benchin::Wrap.new
wrap.call('Sum of strings') do
  ['aa', 'bb', 'cc'].sum
end
#=> 'aabbcc'

@example Nested measurement

wrap = Benchin::Wrap.new
wrap.call('Big calcultation') do
  array = some_expensive_code
  processed = array.map do |data|
    wrap.call('Nested calcultation') do
      some_tranformation(data)
    end
  end
  send_somewhere(processed)
end

@param name [String] name for code block in reporting. @yield code block to execute. @return result of provided block execution.

# File lib/benchin/wrap.rb, line 119
def call(name)
  @current_path.push name
  starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  result = yield
  ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  elapsed = ending - starting

  report.add_time(@current_path, elapsed)
  @current_path.pop

  result
end
reset() click to toggle source

Resets the {#report} to an empty state.

@return [Wrap] self

# File lib/benchin/wrap.rb, line 86
def reset
  @report = Report.new(@name)
  @current_path = []

  self
end
to_h() click to toggle source

Shortcut for `report.to_h`.

@see {Report.to_s} @return [Hash]

# File lib/benchin/wrap.rb, line 144
def to_h
  report.to_s
end
to_s() click to toggle source

Shortcut for `report.to_s`.

@see {Report.to_s} @return [String]

# File lib/benchin/wrap.rb, line 136
def to_s
  report.to_s
end