Skip to main content

qk_cache/
profile.rs

1//! Opt-in elapsed timings for cache operations, written to stderr.
2
3use std::sync::OnceLock;
4use std::time::Instant;
5
6static ENABLED: OnceLock<bool> = OnceLock::new();
7
8/// Enable timings for this process before its first cache operation.
9/// `QK_PROFILE_CACHE=1` also enables them when no caller configures profiling.
10pub fn enable() {
11    let _ = ENABLED.set(true);
12}
13
14pub(crate) struct Span<'a> {
15    task: &'a str,
16    stage: &'static str,
17    started: Option<Instant>,
18}
19
20pub(crate) fn span<'a>(task: &'a str, stage: &'static str) -> Span<'a> {
21    let enabled = *ENABLED
22        .get_or_init(|| std::env::var_os("QK_PROFILE_CACHE").is_some_and(|value| value == "1"));
23    Span {
24        task,
25        stage,
26        started: enabled.then(Instant::now),
27    }
28}
29
30impl Drop for Span<'_> {
31    fn drop(&mut self) {
32        if let Some(started) = self.started {
33            qk_executor::report::output(
34                true,
35                format!(
36                    "qk profile: task={} stage={} ms={:.3}\n",
37                    self.task,
38                    self.stage,
39                    started.elapsed().as_secs_f64() * 1000.0
40                )
41                .as_bytes(),
42            );
43        }
44    }
45}