use spg_engine::Engine;
fn main() {
let shape = std::env::args().nth(1).unwrap_or_else(|| "ts".into());
let rows: i64 = std::env::var("ROWS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(200_000);
let reps: usize = std::env::var("REPS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(20);
let mut eng = Engine::new();
eng.execute(
"CREATE TABLE events (id BIGINT NOT NULL, project_id INT NOT NULL, \
kind TEXT NOT NULL, traits JSONB NOT NULL, received_at TIMESTAMP NOT NULL)",
)
.unwrap();
for i in 1..=rows {
eng.execute(&format!(
"INSERT INTO events VALUES ({i}, {}, '{}', '{{\"plan\":\"{}\",\"country\":\"jp\",\"version\":\"{}\",\"seat\":{}}}', \
timestamp '2026-05-01 00:00:00' + interval '{} minutes')",
(i % 8) + 1,
["open", "click", "deliver", "bounce"][(i % 4) as usize],
["free", "pro", "team"][(i % 3) as usize],
(i % 40) + 1,
i % 500,
i % 129_600,
))
.unwrap();
}
let sql = match shape.as_str() {
"bare" => "SELECT count(*) FROM events",
"int" => "SELECT count(*) FROM events WHERE id > 0",
"ts" => "SELECT count(*) FROM events WHERE received_at > timestamp '1900-01-01'",
"json" => "SELECT count(*) FROM events WHERE traits->>'plan' = 'pro'",
other => panic!("unknown shape {other} — bare | int | ts | json"),
};
eng.execute(sql).unwrap();
#[cfg(feature = "perf-counters")]
{
use core::sync::atomic::Ordering::Relaxed;
let f0 = spg_engine::eval::compiled::STEP_VM_FASTPRED_FIRE.load(Relaxed);
let i0 = spg_engine::eval::compiled::STEP_VM_INTLANE_FIRE.load(Relaxed);
let b0 = spg_engine::eval::compiled::STEP_VM_INTLANE_FALLBACK.load(Relaxed);
eng.execute(sql).unwrap();
println!(
"{shape}: over {rows} rows — fastpred fired {}, intlane fired {}, intlane fell back {}",
spg_engine::eval::compiled::STEP_VM_FASTPRED_FIRE.load(Relaxed) - f0,
spg_engine::eval::compiled::STEP_VM_INTLANE_FIRE.load(Relaxed) - i0,
spg_engine::eval::compiled::STEP_VM_INTLANE_FALLBACK.load(Relaxed) - b0,
);
}
let t0 = std::time::Instant::now();
for _ in 0..reps {
eng.execute(sql).unwrap();
}
let el = t0.elapsed();
println!(
"{shape}: {rows} rows x {reps} reps in {:?} — {:.3} ms/query, {:.1} ns/row",
el,
el.as_secs_f64() * 1000.0 / reps as f64,
el.as_secs_f64() * 1e9 / (reps as f64 * rows as f64),
);
}