Class: Monotonic::Timer

Inherits:
Object
  • Object
show all
Defined in:
lib/Monotonic/Timer.rb

Constant Summary collapse

CLOCK =

Read twice upon every measurement, against a floor of some tens of nanoseconds, so this is the one place here where a constant is worth the rigidity: a method call would be a measurable part of what it measures. It follows .clock_name, and so must come after it.

Process.const_get(clock_name)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.clock_nameObject

An interval is not an instant, and wants a different clock. Upon Darwin CLOCK_UPTIME_RAW advances in some 42ns against the 1000ns of CLOCK_MONOTONIC, and holds while the machine sleeps, which is the right answer for a timed block: a closed lid is not execution. Linux has no such clock, but its CLOCK_MONOTONIC already holds while suspended and advances finely, so the fallback carries the same meaning and not merely the same name.

Which clocks exist is the platform's business, so this is asked rather than declared, as .resolution is.



19
20
21
# File 'lib/Monotonic/Timer.rb', line 19

def clock_name
  @clock_name ||= %i[CLOCK_UPTIME_RAW CLOCK_MONOTONIC].find{|name| Process.const_defined?(name)}
end

.resolutionObject

How finely this clock advances, in nanoseconds. Asked of the platform rather than claimed by the library, and worth asking: a reading is denominated in nanoseconds whether the clock affords them or not.



31
32
33
# File 'lib/Monotonic/Timer.rb', line 31

def resolution
  Process.clock_getres(CLOCK, :nanosecond)
end

.time(&block) ⇒ Object



23
24
25
26
# File 'lib/Monotonic/Timer.rb', line 23

def time(&block)
  timer = Timer.new
  timer.time(&block)
end

Instance Method Details

#startObject



42
43
44
45
# File 'lib/Monotonic/Timer.rb', line 42

def start
  @finish_nanoseconds = nil
  @start_nanoseconds = now
end

#stopObject



47
48
49
# File 'lib/Monotonic/Timer.rb', line 47

def stop
  @finish_nanoseconds = now
end

#timeObject



62
63
64
65
66
67
68
69
70
# File 'lib/Monotonic/Timer.rb', line 62

def time
  start
  begin
    yield self
  ensure
    stop
  end
  total_time
end

#total_nanosecondsObject

Two exact integers differenced, which spends none of the reading. A pair of Floats would not begin to lose the clock at this resolution until some six years of uptime, but they would begin.



54
55
56
# File 'lib/Monotonic/Timer.rb', line 54

def total_nanoseconds
  finish_nanoseconds - @start_nanoseconds
end

#total_timeObject



58
59
60
# File 'lib/Monotonic/Timer.rb', line 58

def total_time
  total_nanoseconds / NANOSECONDS_PER_SECOND.to_f
end