use std::time::Instant;
use spg_engine::Engine;
fn build_5_table_engine() -> Engine {
let mut eng = Engine::new();
for tbl in ["t1", "t2", "t3", "t4", "t5"] {
eng.execute(&format!("CREATE TABLE {tbl} (id INT, peer INT)"))
.expect("create");
for i in 0..50_i64 {
let peer = (i + 1) % 50;
eng.execute(&format!("INSERT INTO {tbl} VALUES ({i}, {peer})"))
.expect("insert");
}
}
eng.execute("ANALYZE").expect("analyze");
eng
}
const COLD_RUNS: u32 = 200;
const HIT_RUNS: u32 = 200;
const ROUNDS: usize = 5;
#[test]
fn prepare_cached_hit_under_1_3_of_cold_path() {
let _lock = crate::perf_lock();
let mut eng = build_5_table_engine();
let sql = "SELECT t1.id FROM t1 \
JOIN t2 ON t1.peer = t2.id \
JOIN t3 ON t2.peer = t3.id \
JOIN t4 ON t3.peer = t4.id \
JOIN t5 ON t4.peer = t5.id \
WHERE t1.id = 1";
let _ = eng.prepare_cached(sql).expect("warm");
let hit_batch = |eng: &mut Engine| {
let t = Instant::now();
for _ in 0..HIT_RUNS {
let stmt = eng.prepare_cached(sql).expect("hit");
std::hint::black_box(stmt);
}
t.elapsed() / HIT_RUNS
};
let cold_batch = |eng: &mut Engine| {
let t = Instant::now();
for _ in 0..COLD_RUNS {
let stmt = eng.prepare(sql).expect("cold");
std::hint::black_box(stmt);
}
t.elapsed() / COLD_RUNS
};
let mut ratios: Vec<f64> = Vec::with_capacity(ROUNDS);
for round in 0..ROUNDS {
let (hit_per_call, cold_per_call) = if round % 2 == 0 {
let h = hit_batch(&mut eng);
let c = cold_batch(&mut eng);
(h, c)
} else {
let c = cold_batch(&mut eng);
let h = hit_batch(&mut eng);
(h, c)
};
let ratio = hit_per_call.as_nanos() as f64 / cold_per_call.as_nanos() as f64;
eprintln!(
"v6.3.0 plan cache gate round {round}: hit/call = {} ns, \
cold/call = {} ns, ratio = {ratio:.3}",
hit_per_call.as_nanos(),
cold_per_call.as_nanos(),
);
ratios.push(ratio);
}
ratios.sort_by(f64::total_cmp);
let median = ratios[ratios.len() / 2];
eprintln!("v6.3.0 plan cache gate: median ratio = {median:.3} over {ROUNDS} rounds");
assert!(
median <= 0.33,
"hit path must be ≤ 1/3 of cold path; median ratio over {ROUNDS} \
interleaved rounds = {median:.3} (rounds: {ratios:?})"
);
}