use fluxbench_ipc::{BenchmarkConfig, Sample, Throughput};
pub const DEFAULT_SAMPLE_COUNT: usize = fluxbench_ipc::DEFAULT_SAMPLE_COUNT as usize;
pub const MIN_SAMPLE_COUNT: usize = 2;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IterationMode {
Simple,
WithSetup,
WithTeardown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MeasureConfig {
pub warmup_ns: u64,
pub measurement_ns: u64,
pub sample_count: usize,
pub fixed_iters_per_sample: Option<u64>,
pub min_iterations: Option<u64>,
pub max_iterations: Option<u64>,
pub track_allocations: bool,
}
impl Default for MeasureConfig {
fn default() -> Self {
Self::from(&BenchmarkConfig::default())
}
}
impl From<&BenchmarkConfig> for MeasureConfig {
fn from(config: &BenchmarkConfig) -> Self {
Self {
warmup_ns: config.warmup_time_ns,
measurement_ns: config.measurement_time_ns,
sample_count: config.sample_count as usize,
fixed_iters_per_sample: config.iters_per_sample,
min_iterations: config.min_iterations,
max_iterations: config.max_iterations,
track_allocations: config.track_allocations,
}
}
}
impl MeasureConfig {
pub fn normalized(mut self) -> Self {
self.sample_count = self.sample_count.max(MIN_SAMPLE_COUNT);
self.fixed_iters_per_sample = self.fixed_iters_per_sample.map(|n| n.max(1));
self
}
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum MeasureError {
#[error("benchmark body never called b.iter*")]
NoIterCall,
#[error("benchmark body called more than one b.iter* method")]
MultipleIterCalls,
#[error("benchmark produced zero samples")]
NoSamples,
#[error("async runtime error: {0}")]
AsyncRuntime(String),
}
#[derive(Debug, Clone)]
pub struct BenchmarkResult {
pub samples: Vec<Sample>,
pub iterations: u64,
pub warmup_iterations: u64,
pub total_time_ns: u64,
pub iters_per_sample: u64,
pub truncated: bool,
pub throughput: Option<Throughput>,
}