corsa 0.3.2

Production-oriented Rust bindings, orchestration layers, and Node integration for typescript-go
Documentation
use std::collections::BTreeMap;
use std::time::{Duration, Instant};

use corsa::{Result, fast::SmallVec};

use crate::{
    profile::{BenchProfiler, ScenarioProfileRow, summarize},
    stats::Stats,
};

pub async fn measure<F, Fut>(iterations: usize, mut f: F) -> Result<Stats>
where
    F: FnMut() -> Fut,
    Fut: std::future::Future<Output = Result<()>>,
{
    let mut samples = SmallVec::<[Duration; 32]>::new();
    let mut index = 0_usize;
    while index < iterations {
        let started = Instant::now();
        f().await?;
        samples.push(started.elapsed());
        index += 1;
    }
    Ok(Stats::from_samples(samples))
}

pub async fn measure_warm<F, Fut>(iterations: usize, mut f: F) -> Result<Stats>
where
    F: FnMut() -> Fut,
    Fut: std::future::Future<Output = Result<()>>,
{
    f().await?;
    measure(iterations, f).await
}

pub async fn measure_profiled<F, Fut>(
    iterations: usize,
    profiler: &BenchProfiler,
    mut f: F,
) -> Result<(Stats, SmallVec<[ScenarioProfileRow; 32]>)>
where
    F: FnMut() -> Fut,
    Fut: std::future::Future<Output = Result<()>>,
{
    let mut samples = SmallVec::<[Duration; 32]>::new();
    let mut profile_samples = BTreeMap::<
        (corsa::fast::CompactString, corsa::fast::CompactString),
        SmallVec<[Duration; 32]>,
    >::new();
    let mut index = 0_usize;
    while index < iterations {
        profiler.clear();
        let started = Instant::now();
        f().await?;
        samples.push(started.elapsed());
        for (key, duration) in profiler.drain_iteration_totals() {
            profile_samples.entry(key).or_default().push(duration);
        }
        index += 1;
    }
    Ok((Stats::from_samples(samples), summarize(profile_samples)))
}

pub async fn measure_warm_profiled<F, Fut>(
    iterations: usize,
    profiler: &BenchProfiler,
    mut f: F,
) -> Result<(Stats, SmallVec<[ScenarioProfileRow; 32]>)>
where
    F: FnMut() -> Fut,
    Fut: std::future::Future<Output = Result<()>>,
{
    profiler.clear();
    f().await?;
    let _ = profiler.drain_iteration_totals();
    measure_profiled(iterations, profiler, f).await
}