circuits-meter
Safe HaskellNone
LanguageGHC2024

Circuit.Meter.Time

Description

Time measurement as a Circuit.

timeX is the canonical Meter for nanosecond timing. All other time combinators are derived from it via meterAction.

Synopsis

Time meter

type Nanos = Integer Source #

Nanoseconds as an integral count.

nanos :: IO Nanos Source #

Read the monotonic clock. Absolute value is not meaningful; use deltas between readings.

On Linux/macOS we use MonotonicRaw for NTP-frequency-adjustment-free timing; on Windows we fall back to the portable Monotonic clock.

timeX :: Meter (K IO) Nanos Nanos Source #

Read clock before and after; return the delta in nanoseconds.

This is a stopwatch: start captures the initial time, and each stop reads the current clock and subtracts. Calling stop multiple times gives cumulative elapsed time since the single start.

Single timing

tick :: (a -> b) -> a -> IO (Nanos, b) Source #

Single timing of a pure function. Returns (nanos, result).

Repeated timing

ticks :: Int -> (a -> b) -> a -> IO ([Nanos], b) Source #

n timings of the same function. Returns ( [nanos], lastResult ).

ticksN :: Int -> (a -> b) -> a -> IO (Nanos, b) Source #

n timings collapsed to a single average nanosecond count.

The computation is run n times; the total time is divided by n.

IO repeated timing

ticksION :: Int -> IO a -> IO (Nanos, a) Source #

n IO timings collapsed to a single average nanosecond count.

Plugin metering

meterIO :: forall a b (t :: Type -> Type -> Type). (a -> IO b) -> Trace t (K IO) a (Nanos, b) Source #

Meter an IO action with timeX.

The result is a Circuit polymorphic in the tensor t, so it can be lifted into pipelines using either (,) (lazy knot-tying) or Either (iteration) without changing the combinator.

meter :: forall a b (t :: Type -> Type -> Type). (a -> b) -> Trace t (K IO) a (Nanos, b) Source #

Meter a pure function with timeX. Forces to WHNF inside the timed bracket so the work cannot be floated out.

Warmup

warmup :: Int -> IO () Source #

Warm up the clock with n dummy reads. Avoids cold-start artefacts.

Reify helper

reifyC :: (Category arr, Traced (,) arr) => Trace (,) arr a b -> arr a b Source #

Reify a circuit using the cartesian tensor (,).

Convenience alias for run with t = (,), used by the runners below to extract a K from a metered circuit.

Single-shot measurement runners

once :: Meter (K IO) a b -> (c -> d) -> c -> IO (b, d) Source #

Measure a single call to a pure function. Forces the result to WHNF inside the timed IO action so the work cannot be floated out.

onceK :: MonadFix m => Meter (K m) a b -> K m c d -> c -> m (b, d) Source #

Measure a single call to a K arrow.

Repeated measurement runners

timesK :: Int -> Int -> Meter (K IO) a b -> K IO c d -> K IO c ([b], d) Source #

Measure a K arrow repeated n times. Returns per-run measurements and the last result.

The step is marked NOINLINE so GHC cannot float the computation out of the timing loop.

>>> import Circuit.Category (K(..))
>>> import Circuit.Meter (Meter(..))
>>> let m = Meter (K $ \_ -> pure 0) (K $ \_ -> pure 0)
>>> runK (timesK 100 3 m (K (pure . (*2)))) 5
([...,...,...],10)