energy-bench 0.3.0

Methods for benchmarking the energy consumption of programs.
Documentation
use std::{io, ops, process::{Child, Command, Stdio}};

use clap::Parser;
use energy_bench::{EnergyBench, EnergyBenchConfig};

#[derive(Parser)]
struct Args {
    #[arg(long)]
    name: String,
    #[command(flatten)]
    config: EnergyBenchConfig,
    #[arg(trailing_var_arg = true)]
    args: Vec<String>,
}

/// Ensure that the spawned process is killed, even if the benchmark is canceled.
struct Guard(Child);

impl ops::Deref for Guard {
    type Target = Child;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl ops::DerefMut for Guard {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl Drop for Guard {
    fn drop(&mut self) {
        let _ = self.0.kill();
        let _ = self.0.wait();
    }
}

fn run(prog: &String, args: &[String]) -> io::Result<()> {
    let mut cmd = Command::new(prog);
    cmd.args(args).stdout(Stdio::null()).stderr(Stdio::null());
    Guard(cmd.spawn()?).wait()?;
    Ok(())
}

fn main() {
    env_logger::init();

    let Args {
        name,
        config,
        args,
    } = Args::parse();

    let (prog, args) = (&args).split_first().expect("no command provided");

    let mut bench = EnergyBench::new(&name, config);
    bench.benchmark(prog, || run(prog, args));
}