1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
# frozen_string_literal: true
# Released under the MIT License.
# Copyright, 2018-2025, by Samuel Williams.
module Async
# A convenient wrapper around the internal monotonic clock.
# @public Since *Async v1*.
class Clock
# Get the current elapsed monotonic time.
def self.now
::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
end
# Measure the execution of a block of code.
# @yields {...} The block to execute.
# @returns [Numeric] The total execution time.
def self.measure
start_time = self.now
yield
return self.now - start_time
end
# Start measuring elapsed time from now.
# @returns [Clock]
def self.start
self.new.tap(&:start!)
end
# Create a new clock with the initial total time.
# @parameter total [Numeric] The initial clock duration.
def initialize(total = 0)
@total = total
@started = nil
end
# @returns [Numeric | Nil] The time when the clock was started, or nil if not started.
attr :started
# Start measuring a duration.
def start!
@started ||= Clock.now
end
# Stop measuring a duration and append the duration to the current total.
def stop!
if @started
@total += (Clock.now - @started)
@started = nil
end
return @total
end
# The total elapsed time including any current duration.
def total
total = @total
if @started
total += (Clock.now - @started)
end
return total
end
# Reset the total elapsed time. If the clock is currently running, reset the start time to now.
def reset!
@total = 0
if @started
@started = Clock.now
end
end
# Convert the clock to a JSON-compatible hash.
#
# @returns [Hash] The JSON-compatible hash.
def as_json(...)
{
started: self.started,
total: self.total,
}
end
# Convert the clock to a JSON string.
#
# @returns [String] The JSON string.
def to_json(...)
self.as_json.to_json(...)
end
end
end
|