Skip to main content

yscv_cli/
benchmark.rs

1use std::time::Duration;
2
3use yscv_eval::{BenchmarkViolation, TimingStats};
4
5#[derive(Debug, Default)]
6pub struct BenchmarkCollector {
7    pub detect: Vec<Duration>,
8    pub track: Vec<Duration>,
9    pub recognize: Vec<Duration>,
10    pub end_to_end: Vec<Duration>,
11}
12
13pub fn format_benchmark_report(report: &yscv_eval::PipelineBenchmarkReport) -> String {
14    let mut output = String::new();
15    output.push_str("benchmark_report_v1\n");
16    output.push_str(&format!("frames={}\n", report.frames));
17    push_stage_stats(&mut output, "detect", &report.detect);
18    push_stage_stats(&mut output, "track", &report.track);
19    push_stage_stats(&mut output, "recognize", &report.recognize);
20    push_stage_stats(&mut output, "end_to_end", &report.end_to_end);
21    output
22}
23
24fn push_stage_stats(output: &mut String, name: &str, stats: &TimingStats) {
25    output.push_str(&format!(
26        "stage={name} runs={} total_ms={:.3} mean_ms={:.3} min_ms={:.3} max_ms={:.3} p50_ms={:.3} p95_ms={:.3} fps={:.3}\n",
27        stats.runs,
28        stats.total_ms,
29        stats.mean_ms,
30        stats.min_ms,
31        stats.max_ms,
32        stats.p50_ms,
33        stats.p95_ms,
34        stats.throughput_fps,
35    ));
36}
37
38pub fn format_benchmark_violations(violations: &[BenchmarkViolation]) -> String {
39    let mut output = String::new();
40    for violation in violations {
41        output.push_str(&format!(
42            "  - {}.{} expected {:.3}, observed {:.3}\n",
43            violation.stage, violation.metric, violation.expected, violation.observed
44        ));
45    }
46    output
47}