use selen::prelude::*;
use std::time::Instant;
fn get_memory_usage() -> usize {
std::process::Command::new("ps")
.args(&["-o", "rss=", "-p", &std::process::id().to_string()])
.output()
.ok()
.and_then(|output| String::from_utf8(output.stdout).ok())
.and_then(|s| s.trim().parse::<usize>().ok())
.unwrap_or(0) / 1024 }
fn main() {
println!("๐งช Memory Usage During Variable Creation Test");
println!("=============================================");
let initial_memory = get_memory_usage();
println!("Initial memory usage: {} MB", initial_memory);
println!("\nTest: Creating variables and monitoring memory...");
let config = SolverConfig::default()
.with_max_memory_mb(10) .with_timeout_ms(10000);
let mut m = Model::with_config(config);
let mut variables = Vec::new();
for i in 0..100 { let current_memory = get_memory_usage();
let memory_increase = current_memory.saturating_sub(initial_memory);
if i % 10 == 0 {
println!(" Step {}: Created {} variables, Memory: +{} MB (total: {} MB)",
i, variables.len(), memory_increase, current_memory);
if memory_increase > 200 {
println!(" โ ๏ธ Memory usage growing too fast, stopping variable creation");
break;
}
}
let x = m.float(0.0, 100.0);
let y = m.float(0.0, 100.0);
let z = m.add(x, y);
m.new(z.gt(float(50.0)));
variables.push((x, y, z));
if memory_increase > 100 {
println!(" โ ๏ธ Reached practical memory limit ({} MB increase), testing solve...", memory_increase);
break;
}
}
let pre_solve_memory = get_memory_usage();
println!("\nPre-solve memory: {} MB (+{} MB from start)",
pre_solve_memory, pre_solve_memory.saturating_sub(initial_memory));
println!("Attempting to solve with {} variables...", variables.len() * 3);
let start = Instant::now();
let result = m.solve();
let duration = start.elapsed();
let post_solve_memory = get_memory_usage();
match result {
Ok(_) => {
println!(" โ
Solved successfully in {:.3}s", duration.as_secs_f64());
println!(" Memory after solve: {} MB", post_solve_memory);
},
Err(e) => {
println!(" โ Failed: {} in {:.3}s", e, duration.as_secs_f64());
println!(" Memory when failed: {} MB", post_solve_memory);
if format!("{}", e).contains("Memory") || format!("{}", e).contains("memory") {
println!(" โ
Memory limit working correctly!");
} else {
println!(" โ Failed for different reason - memory limits may not be working");
}
}
}
println!("\n๐ Analysis:");
println!("- Variable creation used: {} MB", pre_solve_memory.saturating_sub(initial_memory));
println!("- Solving used additional: {} MB", post_solve_memory.saturating_sub(pre_solve_memory));
println!("- Total memory increase: {} MB", post_solve_memory.saturating_sub(initial_memory));
if pre_solve_memory.saturating_sub(initial_memory) > 50 {
println!("โ ๏ธ WARNING: Variable creation alone used significant memory!");
println!(" This suggests we need memory limits during model building, not just solving.");
}
}