1use std::cell::Cell;
6use std::sync::OnceLock;
7use std::time::{Duration, Instant};
8
9fn start() -> Option<Instant> {
10 static START: OnceLock<Option<Instant>> = OnceLock::new();
11 *START.get_or_init(|| std::env::var_os("RETEX_TIMING").map(|_| Instant::now()))
12}
13
14pub fn enabled() -> bool {
16 start().is_some()
17}
18
19pub fn mark(label: &str) {
21 if let Some(t0) = start() {
22 eprintln!(
23 "[timing] {:>9.3} ms {label}",
24 t0.elapsed().as_secs_f64() * 1e3
25 );
26 }
27}
28
29#[derive(Default)]
31pub struct Accumulator {
32 total: Cell<Duration>,
33 count: Cell<u64>,
34}
35
36impl Accumulator {
37 pub fn add(&self, since: Instant) {
39 self.total.set(self.total.get() + since.elapsed());
40 self.count.set(self.count.get() + 1);
41 }
42
43 pub fn report(&self, label: &str) {
45 if enabled() {
46 eprintln!(
47 "[timing] {:>9.3} ms total in {label} ({} calls)",
48 self.total.get().as_secs_f64() * 1e3,
49 self.count.get()
50 );
51 }
52 }
53}
54
55thread_local! {
56 pub static LUA: Accumulator = Accumulator::default();
58 pub static FONTS: Accumulator = Accumulator::default();
60}