Skip to main content

mobench_sdk/
metrics.rs

1//! Custom benchmark metrics captured alongside timed samples.
2//!
3//! Benchmark functions can record small scalar outputs, such as serialized
4//! proof length. The native JSON ABI attaches them after timing completes.
5
6use {
7    serde::Serialize,
8    std::{cell::RefCell, collections::BTreeMap},
9};
10
11/// Additional scalar metrics emitted by one native benchmark run.
12#[derive(Debug, Default, Serialize)]
13pub struct CustomMetrics {
14    /// One value per warmup or measured invocation, in execution order.
15    pub sample_u64: BTreeMap<String, Vec<u64>>,
16    /// Run-wide values such as a deduplicated proving-payload size.
17    pub run_u64: BTreeMap<String, u64>,
18}
19
20thread_local! {
21    static CUSTOM_METRICS: RefCell<CustomMetrics> = RefCell::new(CustomMetrics::default());
22}
23
24/// Records an unsigned scalar for the current benchmark invocation.
25pub fn record_sample_u64(name: impl Into<String>, value: u64) {
26    CUSTOM_METRICS.with(|metrics| {
27        metrics
28            .borrow_mut()
29            .sample_u64
30            .entry(name.into())
31            .or_default()
32            .push(value);
33    });
34}
35
36/// Records or replaces an unsigned run-wide scalar.
37pub fn record_run_u64(name: impl Into<String>, value: u64) {
38    CUSTOM_METRICS.with(|metrics| {
39        metrics.borrow_mut().run_u64.insert(name.into(), value);
40    });
41}
42
43#[cfg(feature = "registry")]
44pub(crate) fn clear() {
45    CUSTOM_METRICS.with(|metrics| *metrics.borrow_mut() = CustomMetrics::default());
46}
47
48#[cfg(feature = "registry")]
49pub(crate) fn take() -> CustomMetrics {
50    CUSTOM_METRICS.with(|metrics| std::mem::take(&mut *metrics.borrow_mut()))
51}
52
53impl CustomMetrics {
54    #[cfg(feature = "registry")]
55    pub(crate) fn is_empty(&self) -> bool {
56        self.sample_u64.is_empty() && self.run_u64.is_empty()
57    }
58}