simplebench_runtime/progress.rs
1//! Progress reporting for benchmark execution.
2//!
3//! Emits JSON progress messages to stderr during warmup and sample collection.
4//! The CLI tool parses these to display progress bars.
5
6use serde::Serialize;
7
8/// Progress phase during benchmark execution.
9#[derive(Debug, Clone, Serialize)]
10#[serde(tag = "phase")]
11pub enum ProgressPhase {
12 /// Warmup phase - running iterations to stabilize CPU/cache state.
13 #[serde(rename = "warmup")]
14 Warmup {
15 /// Milliseconds elapsed so far.
16 elapsed_ms: u64,
17 /// Target warmup duration in milliseconds.
18 target_ms: u64,
19 },
20 /// Sample collection phase.
21 #[serde(rename = "samples")]
22 Samples {
23 /// Current sample index (0-based).
24 current: u32,
25 /// Total number of samples to collect.
26 total: u32,
27 },
28 /// Benchmark complete.
29 #[serde(rename = "complete")]
30 Complete,
31}
32
33/// Progress message emitted to stderr during benchmark execution.
34#[derive(Debug, Clone, Serialize)]
35pub struct ProgressMessage<'a> {
36 /// Benchmark name.
37 pub bench: &'a str,
38 /// Current phase and its data.
39 #[serde(flatten)]
40 pub phase: ProgressPhase,
41}
42
43/// Check if progress output is enabled (not suppressed via env var).
44fn progress_enabled() -> bool {
45 std::env::var("SIMPLEBENCH_QUIET").is_err()
46}
47
48/// Emit progress JSON to stderr (non-blocking, fire-and-forget).
49///
50/// Output is wrapped in `{"progress": ...}` envelope to distinguish
51/// from other stderr output (warnings, errors).
52pub fn emit_progress(msg: &ProgressMessage) {
53 if !progress_enabled() {
54 return;
55 }
56
57 // Wrap in {"progress": ...} envelope
58 if let Ok(json) = serde_json::to_string(&serde_json::json!({"progress": msg})) {
59 eprintln!("{}", json);
60 }
61}