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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Lightweight iteration timing utilities.
//!
//! This module provides helpers to measure and report iteration times
//! in long-running loops, e.g. when combined with a progress bar
//! (see the `progress` feature).
//!
//! Components
//! -----------------
//! * [`IterTimer`] – Tracks per-iteration durations and computes a
//! smoothed **exponential moving average** (EMA).
//! Useful to get a stable estimate of iteration time even when
//! individual steps fluctuate.
//!
//! * [`fmt_dur`] – Human-readable formatter for [`Duration`] values,
//! producing strings like `"253µs"`, `"42ms"`, or `"3.14s"` depending
//! on the scale.
//!
//! Usage
//! -----------------
//! Typical workflow inside a loop:
//!
//! ```rust, no_run
//! use std::time::Duration;
//! use your_crate::iter_timer::{IterTimer, fmt_dur};
//!
//! let mut timer = IterTimer::new(0.2); // smoothing factor α = 0.2
//!
//! for i in 0..10 {
//! // ... some expensive work ...
//!
//! let dt = timer.tick();
//! println!(
//! "iter {i} took {}, EMA = {}",
//! fmt_dur(dt),
//! fmt_dur(timer.avg())
//! );
//! }
//! ```
//!
//! Design notes
//! -----------------
//! * The EMA update rule is:
//! `ema ← α·dt + (1–α)·ema`
//! with `α ∈ (0,1]`.
//! - `α = 1.0` → no smoothing (EMA = last sample).
//! - small `α` → stronger smoothing, slower adaptation.
//!
//! * [`IterTimer::tick`] must be called at each iteration boundary.
//! The first tick initializes the average to the first duration.
//!
//! * [`IterTimer::avg`] returns the smoothed duration as a [`Duration`].
//!
//! * This module is enabled only with the `progress` feature.
use ;