use std::time::{Duration, Instant};
use supermachine::Image;
const SOURCE: &[u8] = b"fn main() { println!(\"hello\"); }";
const CMD: &[&str] = &["sh", "-c", "rustc -O /tmp/main.rs -o /tmp/m && /tmp/m"];
fn main() -> Result<(), Box<dyn std::error::Error>> {
let snap = format!("{}/.local/supermachine-snapshots/rust_1_slim", std::env::var("HOME")?);
let image = Image::from_snapshot(&snap)?;
let pool_size: usize = std::env::var("POOL").ok().and_then(|s| s.parse().ok()).unwrap_or(1);
let pool = image.pool().min(pool_size).max(pool_size).idle_timeout(Duration::MAX).build()?;
println!("pool: min={pool_size} max={pool_size}");
let n: usize = std::env::var("N").ok().and_then(|s| s.parse().ok()).unwrap_or(10);
let mut sums = [0u128; 4];
println!("=== {n} cycles, breakdown (µs) ===");
println!(" cycle | acq | wfile | exec | drop | total");
for i in 0..n {
let t0 = Instant::now();
let vm = pool.acquire()?;
let t1 = Instant::now();
vm.write_file("/tmp/main.rs", SOURCE)?;
let t2 = Instant::now();
let _ = vm.exec_builder().argv(CMD.iter().copied()).timeout(Duration::from_secs(60)).output()?;
let t3 = Instant::now();
drop(vm);
let t4 = Instant::now();
let acq = (t1 - t0).as_micros();
let wf = (t2 - t1).as_micros();
let ex = (t3 - t2).as_micros();
let dr = (t4 - t3).as_micros();
let total = (t4 - t0).as_micros();
sums[0] += acq; sums[1] += wf; sums[2] += ex; sums[3] += dr;
if i < 3 || i == n - 1 {
println!(" {i:5} | {acq:>6} | {wf:>7} | {ex:>7} | {dr:>6} | {total:>6}");
} else if i == 3 {
println!(" ... ");
}
}
let avg = |s: u128| s / n as u128;
let total: u128 = sums.iter().sum::<u128>() / n as u128;
println!("\n avg | {:>6} | {:>7} | {:>7} | {:>6} | {:>6}",
avg(sums[0]), avg(sums[1]), avg(sums[2]), avg(sums[3]), total);
println!("\n rustc share: {:.1}%", (sums[2] as f64 / sums.iter().sum::<u128>() as f64) * 100.0);
println!(" supermachine overhead per cycle: {} µs", avg(sums[0]) + avg(sums[1]) + avg(sums[3]));
Ok(())
}