84 lines
2.8 KiB
Rust
84 lines
2.8 KiB
Rust
// ============================================================
|
|
// 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<serde_json::Value> = (0..N).map(|i| json!({"i": i})).collect();
|
|
let specs: Vec<RowSpec> = 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());
|
|
}
|