// ============================================================ // EXAMPLE: bench_append // PURPOSE: Measure fsync-amortization speedup of append_batch over // a loop of append() calls on a file-backed SQLite DB. // Intended for ad-hoc inspection, not CI regression // tracking (no criterion / no gate). Prints rows/sec + // speedup ratio. // // RUN: cargo run -p trusty-sqlite --release --example bench_append // (release mode matters: debug rusqlite is much slower) // ============================================================ use serde_json::json; use std::time::Instant; use trusty_core::SecretKey; use trusty_sqlite::{RowSpec, Trusty}; const N: usize = 1000; fn tmp_db_path(tag: &str) -> std::path::PathBuf { let mut p = std::env::temp_dir(); let nanos = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .map(|d| d.as_nanos()) .unwrap_or(0); p.push(format!("trusty_bench_{tag}_{nanos}.db")); p } fn key() -> SecretKey { SecretKey::new(*b"0123456789abcdef") } fn bench_single_row(path: &std::path::Path) -> f64 { let mut t = Trusty::open(path, key()).expect("open"); // Warmup: one genesis so we are measuring mutations, not first-row setup. t.append("acme", &json!({"warmup": true}), "s") .expect("warmup"); let start = Instant::now(); for i in 0..N { t.append("acme", &json!({"i": i}), "s").expect("append ok"); } let elapsed = start.elapsed().as_secs_f64(); N as f64 / elapsed } fn bench_batch(path: &std::path::Path) -> f64 { let mut t = Trusty::open(path, key()).expect("open"); t.append("acme", &json!({"warmup": true}), "s") .expect("warmup"); let values: Vec = (0..N).map(|i| json!({"i": i})).collect(); let specs: Vec = values .iter() .map(|v| RowSpec { entity_id: "acme", data: v, source_url: "s", }) .collect(); let start = Instant::now(); t.append_batch(&specs).expect("batch ok"); let elapsed = start.elapsed().as_secs_f64(); N as f64 / elapsed } fn main() { let p1 = tmp_db_path("single"); let p2 = tmp_db_path("batch"); println!("trusty-sqlite append benchmark (N = {N}, file-backed, WAL + FULL sync)"); println!("single-row db : {}", p1.display()); println!("batch db : {}", p2.display()); println!(); let single_rps = bench_single_row(&p1); let batch_rps = bench_batch(&p2); let speedup = batch_rps / single_rps; println!("single-row append : {single_rps:>10.1} rows/sec"); println!("append_batch : {batch_rps:>10.1} rows/sec"); println!("speedup : {speedup:>10.2}x"); println!(); println!("(cleanup: rm {} {})", p1.display(), p2.display()); }