use std::sync::OnceLock;
use std::time::Instant;
static ENABLED: OnceLock<bool> = OnceLock::new();
pub fn enable() {
let _ = ENABLED.set(true);
}
pub(crate) struct Span<'a> {
task: &'a str,
stage: &'static str,
started: Option<Instant>,
counts: Vec<(&'static str, u64)>,
}
pub(crate) fn span<'a>(task: &'a str, stage: &'static str) -> Span<'a> {
let enabled = *ENABLED
.get_or_init(|| std::env::var_os("QK_PROFILE_CACHE").is_some_and(|value| value == "1"));
Span {
task,
stage,
started: enabled.then(Instant::now),
counts: Vec::new(),
}
}
impl Span<'_> {
pub(crate) fn count(&mut self, name: &'static str, value: u64) {
if self.started.is_some() {
self.counts.push((name, value));
}
}
}
impl Drop for Span<'_> {
fn drop(&mut self) {
if let Some(started) = self.started {
let mut line = format!(
"qk profile: task={} stage={} ms={:.3}",
self.task,
self.stage,
started.elapsed().as_secs_f64() * 1000.0
);
for (name, value) in &self.counts {
line.push_str(&format!(" {name}={value}"));
}
line.push('\n');
qk_executor::report::output(true, line.as_bytes());
}
}
}