use std::hint::black_box;
use criterion::{Criterion, criterion_group, criterion_main};
use powerio::{TargetFormat, parse_matpower, parse_str, write_as, write_matpower};
const CASES: &[&str] = &["case57", "case118", "case2869pegase"];
fn src(case: &str) -> String {
std::fs::read_to_string(format!("../tests/data/{case}.m")).unwrap()
}
fn bench_parse(c: &mut Criterion) {
for case in CASES {
let s = src(case);
c.bench_function(&format!("parse_{case}"), |b| {
b.iter(|| parse_matpower(black_box(&s)).unwrap());
});
}
}
fn bench_roundtrip(c: &mut Criterion) {
for case in CASES {
let s = src(case);
let parsed = parse_matpower(&s).unwrap();
c.bench_function(&format!("write_{case}"), |b| {
b.iter(|| write_matpower(black_box(&parsed)));
});
c.bench_function(&format!("roundtrip_{case}"), |b| {
b.iter(|| write_matpower(&parse_matpower(black_box(&s)).unwrap()));
});
}
}
const FORMATS: &[(&str, TargetFormat)] = &[
("powermodels-json", TargetFormat::PowerModelsJson),
("psse", TargetFormat::Psse { rev: 33 }),
("powerworld", TargetFormat::PowerWorld),
("egret-json", TargetFormat::EgretJson),
];
fn bench_parse_formats(c: &mut Criterion) {
let case = "case118";
let net = parse_matpower(&src(case)).unwrap();
for (name, fmt) in FORMATS {
let text = write_as(&net, *fmt).unwrap().text;
parse_str(&text, name)
.unwrap_or_else(|e| panic!("{name} writer output did not reparse: {e}"));
c.bench_function(&format!("parse_{name}_{case}"), |b| {
b.iter(|| parse_str(black_box(&text), name).unwrap());
});
}
}
fn bench_powerworld_pwb(c: &mut Criterion) {
let pairs: &[(&str, &str, &str)] = &[
(
"activsg200",
"../tests/data/powerworld/ACTIVSg200.aux",
"../tests/data/powerworld/ACTIVSg200.pwb",
),
(
"activsg2000",
"../tests/data/large/ACTIVSg2000/Texas2000_June2016.AUX",
"../tests/data/large/ACTIVSg2000/Texas2000_June2016.pwb",
),
("rts_gmlc", "", "../tests/data/large/RTS-GMLC/RTS-GMLC.PWB"),
];
let mut aux_jobs: Vec<(String, String)> = Vec::new();
let mut pwb_jobs: Vec<(String, Vec<u8>)> = Vec::new();
for (label, aux, pwb) in pairs {
if let Ok(text) = std::fs::read_to_string(aux) {
aux_jobs.push((format!("parse_aux_{label}"), text));
}
if let Ok(bytes) = std::fs::read(pwb) {
pwb_jobs.push((format!("parse_pwb_{label}"), bytes));
}
}
if let Ok(path) = std::env::var("POWERIO_BENCH_AUX") {
aux_jobs.push((
"parse_aux_extra".into(),
std::fs::read_to_string(path).unwrap(),
));
}
if let Ok(path) = std::env::var("POWERIO_BENCH_PWB") {
pwb_jobs.push(("parse_pwb_extra".into(), std::fs::read(path).unwrap()));
}
for (name, text) in &aux_jobs {
c.bench_function(name, |b| {
b.iter(|| parse_str(black_box(text), "aux").unwrap());
});
}
for (name, bytes) in &pwb_jobs {
c.bench_function(name, |b| {
b.iter(|| powerio::format::powerworld::parse_pwb(black_box(bytes), None).unwrap());
});
}
}
fn bench_powerworld_pwd(c: &mut Criterion) {
let Ok(bytes) = std::fs::read("../tests/data/powerworld/ACTIVSg200.pwd") else {
return;
};
c.bench_function("parse_pwd_activsg200", |b| {
b.iter(|| powerio::format::powerworld::parse_pwd(black_box(&bytes)).unwrap());
});
}
criterion_group!(
benches,
bench_parse,
bench_roundtrip,
bench_parse_formats,
bench_powerworld_pwb,
bench_powerworld_pwd
);
criterion_main!(benches);