211 lines
6.9 KiB
Rust
211 lines
6.9 KiB
Rust
use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
|
|
use hero_supervisor_openrpc_client::SupervisorClientBuilder;
|
|
use hero_job::Job;
|
|
use tokio::runtime::Runtime;
|
|
use std::time::Duration;
|
|
use std::collections::HashMap;
|
|
use uuid::Uuid;
|
|
use chrono::Utc;
|
|
|
|
const SUPERVISOR_URL: &str = "http://127.0.0.1:3030";
|
|
const ADMIN_SECRET: &str = "SECRET";
|
|
|
|
fn create_runtime() -> Runtime {
|
|
Runtime::new().unwrap()
|
|
}
|
|
|
|
fn create_test_job(runner: &str, command: &str, args: Vec<String>) -> Job {
|
|
Job {
|
|
id: Uuid::new_v4().to_string(),
|
|
caller_id: "benchmark".to_string(),
|
|
context_id: "test".to_string(),
|
|
payload: serde_json::json!({
|
|
"command": command,
|
|
"args": args
|
|
}).to_string(),
|
|
runner: runner.to_string(),
|
|
timeout: 30,
|
|
env_vars: HashMap::new(),
|
|
created_at: Utc::now(),
|
|
updated_at: Utc::now(),
|
|
signatures: vec![],
|
|
}
|
|
}
|
|
|
|
#[cfg(target_os = "macos")]
|
|
fn get_memory_usage() -> Option<usize> {
|
|
use std::process::Command;
|
|
let output = Command::new("ps")
|
|
.args(&["-o", "rss=", "-p", &std::process::id().to_string()])
|
|
.output()
|
|
.ok()?;
|
|
String::from_utf8(output.stdout)
|
|
.ok()?
|
|
.trim()
|
|
.parse::<usize>()
|
|
.ok()
|
|
.map(|kb| kb * 1024)
|
|
}
|
|
|
|
#[cfg(target_os = "linux")]
|
|
fn get_memory_usage() -> Option<usize> {
|
|
use std::fs;
|
|
let status = fs::read_to_string("/proc/self/status").ok()?;
|
|
for line in status.lines() {
|
|
if line.starts_with("VmRSS:") {
|
|
let kb = line.split_whitespace().nth(1)?.parse::<usize>().ok()?;
|
|
return Some(kb * 1024);
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
fn memory_job_creation(c: &mut Criterion) {
|
|
let rt = create_runtime();
|
|
let client = rt.block_on(async {
|
|
SupervisorClientBuilder::new()
|
|
.url(SUPERVISOR_URL)
|
|
.secret(ADMIN_SECRET)
|
|
.build()
|
|
.expect("Failed to create client")
|
|
});
|
|
|
|
rt.block_on(async {
|
|
let _ = client.runner_create("hero").await;
|
|
});
|
|
|
|
let mut group = c.benchmark_group("memory_job_creation");
|
|
|
|
for num_jobs in [10, 50, 100, 200].iter() {
|
|
group.bench_with_input(
|
|
BenchmarkId::from_parameter(num_jobs),
|
|
num_jobs,
|
|
|b, &num_jobs| {
|
|
b.iter_custom(|iters| {
|
|
let mut total_duration = Duration::ZERO;
|
|
|
|
for _ in 0..iters {
|
|
let mem_before = get_memory_usage().unwrap_or(0);
|
|
|
|
let start = std::time::Instant::now();
|
|
rt.block_on(async {
|
|
let mut jobs = Vec::new();
|
|
for i in 0..num_jobs {
|
|
let job = create_test_job("hero", "echo", vec![format!("mem_test_{}", i)]);
|
|
jobs.push(job);
|
|
}
|
|
black_box(jobs);
|
|
});
|
|
total_duration += start.elapsed();
|
|
|
|
let mem_after = get_memory_usage().unwrap_or(0);
|
|
let mem_delta = mem_after.saturating_sub(mem_before);
|
|
|
|
if mem_delta > 0 {
|
|
eprintln!("Memory delta for {} jobs: {} KB", num_jobs, mem_delta / 1024);
|
|
}
|
|
}
|
|
|
|
total_duration
|
|
});
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
fn memory_client_creation(c: &mut Criterion) {
|
|
let rt = create_runtime();
|
|
|
|
let mut group = c.benchmark_group("memory_client_creation");
|
|
|
|
for num_clients in [1, 10, 50, 100].iter() {
|
|
group.bench_with_input(
|
|
BenchmarkId::from_parameter(num_clients),
|
|
num_clients,
|
|
|b, &num_clients| {
|
|
b.iter_custom(|iters| {
|
|
let mut total_duration = Duration::ZERO;
|
|
|
|
for _ in 0..iters {
|
|
let mem_before = get_memory_usage().unwrap_or(0);
|
|
|
|
let start = std::time::Instant::now();
|
|
rt.block_on(async {
|
|
let mut clients = Vec::new();
|
|
for _ in 0..num_clients {
|
|
let client = SupervisorClientBuilder::new()
|
|
.url(SUPERVISOR_URL)
|
|
.secret(ADMIN_SECRET)
|
|
.build()
|
|
.expect("Failed to create client");
|
|
clients.push(client);
|
|
}
|
|
black_box(clients);
|
|
});
|
|
total_duration += start.elapsed();
|
|
|
|
let mem_after = get_memory_usage().unwrap_or(0);
|
|
let mem_delta = mem_after.saturating_sub(mem_before);
|
|
|
|
if mem_delta > 0 {
|
|
eprintln!("Memory delta for {} clients: {} KB", num_clients, mem_delta / 1024);
|
|
}
|
|
}
|
|
|
|
total_duration
|
|
});
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
fn memory_payload_sizes(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("memory_payload_sizes");
|
|
|
|
for size_kb in [1, 10, 100, 1000].iter() {
|
|
group.bench_with_input(
|
|
BenchmarkId::from_parameter(format!("{}KB", size_kb)),
|
|
size_kb,
|
|
|b, &size_kb| {
|
|
b.iter_custom(|iters| {
|
|
let mut total_duration = Duration::ZERO;
|
|
|
|
for _ in 0..iters {
|
|
let mem_before = get_memory_usage().unwrap_or(0);
|
|
|
|
let start = std::time::Instant::now();
|
|
let large_data = "x".repeat(size_kb * 1024);
|
|
let job = create_test_job("hero", "echo", vec![large_data]);
|
|
black_box(job);
|
|
total_duration += start.elapsed();
|
|
|
|
let mem_after = get_memory_usage().unwrap_or(0);
|
|
let mem_delta = mem_after.saturating_sub(mem_before);
|
|
|
|
if mem_delta > 0 {
|
|
eprintln!("Memory delta for {}KB payload: {} KB", size_kb, mem_delta / 1024);
|
|
}
|
|
}
|
|
|
|
total_duration
|
|
});
|
|
},
|
|
);
|
|
}
|
|
|
|
group.finish();
|
|
}
|
|
|
|
criterion_group!(
|
|
memory_benches,
|
|
memory_job_creation,
|
|
memory_client_creation,
|
|
memory_payload_sizes,
|
|
);
|
|
|
|
criterion_main!(memory_benches);
|