use codescout::agent::Agent;
use std::path::Path;
use std::time::Instant;
use tempfile::TempDir;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut args = std::env::args().skip(1);
let n_projects: usize = args.next().and_then(|s| s.parse().ok()).unwrap_or(8);
let n_passes: usize = args.next().and_then(|s| s.parse().ok()).unwrap_or(50);
let dirs: Vec<TempDir> = (0..n_projects)
.map(|i| {
let dir = tempfile::tempdir()?;
seed_project(dir.path(), i)?;
anyhow::Ok(dir)
})
.collect::<anyhow::Result<_>>()?;
let agent = Agent::new(None).await?;
println!("iter,project,elapsed_ms,vm_size_kb,vm_rss_kb,vm_data_kb,vm_peak_kb");
let baseline = read_self_memory_kb();
println!(
"baseline,-,0,{},{},{},{}",
baseline.size, baseline.rss, baseline.data, baseline.peak
);
let mut iter = 0usize;
for pass in 0..n_passes {
for (idx, dir) in dirs.iter().enumerate() {
iter += 1;
let t = Instant::now();
agent
.activate(dir.path().to_path_buf(), Some(false))
.await?;
let elapsed_ms = t.elapsed().as_millis();
if idx == 0 || pass == n_passes - 1 {
let m = read_self_memory_kb();
println!(
"{},{},{},{},{},{},{}",
iter, idx, elapsed_ms, m.size, m.rss, m.data, m.peak
);
}
}
}
Ok(())
}
fn seed_project(root: &Path, idx: usize) -> anyhow::Result<()> {
std::fs::create_dir_all(root.join("src"))?;
for i in 0..3 {
let body = format!("pub fn f_{idx}_{i}(x: i32) -> i32 {{ x + {i} }}\n");
std::fs::write(root.join(format!("src/m{i}.rs")), body)?;
}
let cargo =
format!("[package]\nname = \"probe_p{idx}\"\nversion = \"0.0.1\"\nedition = \"2021\"\n");
std::fs::write(root.join("Cargo.toml"), cargo)?;
Ok(())
}
#[derive(Default, Copy, Clone)]
struct Mem {
size: u64,
rss: u64,
data: u64,
peak: u64,
}
fn read_self_memory_kb() -> Mem {
let mut out = Mem::default();
let Ok(text) = std::fs::read_to_string("/proc/self/status") else {
return out;
};
for line in text.lines() {
let Some((key, rest)) = line.split_once(':') else {
continue;
};
let v = rest
.split_whitespace()
.next()
.and_then(|n| n.parse::<u64>().ok())
.unwrap_or(0);
match key {
"VmSize" => out.size = v,
"VmRSS" => out.rss = v,
"VmData" => out.data = v,
"VmPeak" => out.peak = v,
_ => {}
}
}
out
}