philiprehberger-stopwatch
Precision stopwatch with lap timing, pause/resume, and formatted output
Requirements
- Ruby >= 3.1
Installation
Add to your Gemfile:
gem "philiprehberger-stopwatch"
Or install directly:
gem install philiprehberger-stopwatch
Usage
require "philiprehberger/stopwatch"
sw = Philiprehberger::Stopwatch.new
sw.start
# ... do work ...
sw.lap('phase 1')
# ... do more work ...
sw.lap('phase 2')
sw.stop
sw.elapsed # => 1.234 (seconds)
sw.laps # => [{name: "phase 1", elapsed: 0.5, split: 0.5}, {name: "phase 2", elapsed: 0.734, split: 1.234}]
Pause and Resume
sw = Philiprehberger::Stopwatch.new
sw.start
sleep(0.1)
sw.pause # alias for #stop
sw.resume # alias for #start
sleep(0.1)
sw.stop
sw.elapsed # => ~0.2 (paused time not counted)
Restart
sw = Philiprehberger::Stopwatch.new
sw.start
sleep(0.1)
sw.lap('phase 1')
sw.restart # equivalent to #reset followed by #start
sleep(0.05)
sw.elapsed # => ~0.05 (prior state cleared)
Formatted Output
sw = Philiprehberger::Stopwatch.new
sw.start
sleep(0.5)
sw.formatted_elapsed # => "500.12ms"
sleep(65)
sw.formatted_elapsed # => "1m 5s"
Lap Statistics
sw = Philiprehberger::Stopwatch.new
sw.start
sw.lap('setup')
sw.lap('process')
sw.lap('teardown')
sw.lap_stats
# => { count: 3, total: 0.053, avg: 0.018, min: 0.005, max: 0.031 }
sw.formatted_laps
# => [{ name: "setup", elapsed: 0.005, formatted: "5.00ms" }, ...]
Serialization
sw = Philiprehberger::Stopwatch.new
sw.start
sw.lap('setup')
sw.lap('process')
sw.stop
sw.to_h
# => { running: false, paused: true, elapsed: 0.053,
# formatted_elapsed: "53.00ms", laps: [...], lap_stats: {...} }
Named Checkpoints
sw = Philiprehberger::Stopwatch.new
sw.start
sleep(0.1)
sw.checkpoint('after_setup')
sleep(0.2)
sw.checkpoint('after_process')
sw.elapsed_at('after_setup') # => ~0.1 (cumulative split at that moment)
sw.elapsed_at('after_process') # => ~0.3
sw.since('after_setup') # => ~0.2 (time elapsed since that checkpoint)
sw.since('after_process') # => ~0.0
sw.checkpoints
# => { "after_setup" => 0.1003, "after_process" => 0.3007 }
Block Timing
result, elapsed = Philiprehberger::Stopwatch.measure { expensive_operation }
puts "Took #{elapsed} seconds"
formatted = Philiprehberger::Stopwatch.measure_formatted { expensive_operation }
puts "Took #{formatted}" # => "Took 12.50ms"
API
| Method | Description |
|---|---|
Stopwatch.new |
Create a new stopwatch |
#start |
Start or resume the stopwatch |
#stop |
Pause the stopwatch |
#pause |
Alias for #stop |
#resume |
Alias for #start (resumes a paused stopwatch) |
#reset |
Reset all state |
#restart |
Reset and start the stopwatch in one call |
#lap(name) |
Record a lap with optional name |
#elapsed |
Total elapsed time in seconds |
#elapsed_ms |
Total elapsed time in milliseconds |
#elapsed_us |
Total elapsed time in microseconds |
#laps |
Array of recorded lap data |
#running? |
Whether the stopwatch is actively running |
#paused? |
Whether the stopwatch is paused |
#checkpoint(name) |
Record a named moment storing the current cumulative split time |
#elapsed_at(name) |
Cumulative split time at the named checkpoint |
#since(name) |
Elapsed time since the named checkpoint was recorded |
#checkpoints |
Hash of all recorded checkpoints |
#lap_stats |
Aggregate lap statistics (count, total, avg, min, max) |
#formatted_elapsed |
Human-readable elapsed time string |
#formatted_laps |
Array of laps with formatted times |
#to_h |
Serialize full stopwatch state to a hash |
Stopwatch.measure { block } |
Measure block execution time |
Stopwatch.measure_formatted { block } |
Measure block and return formatted string |
Development
bundle install
bundle exec rspec
bundle exec rubocop
Support
If you find this project useful: