use std::hint::black_box;
use std::time::Instant;
const WARMUP: usize = 2_000;
const ITERS: usize = 200_000;
fn setup() {
let dir = Box::leak(Box::new(tempfile::tempdir().expect("tempdir")));
let npub: &'static str = Box::leak(format!("npub1{}", "q".repeat(58)).into_boxed_str());
std::fs::create_dir_all(dir.path().join(npub)).expect("account dir");
vector_core::db::set_app_data_dir(dir.path().to_path_buf());
vector_core::db::set_current_account(npub.to_string()).expect("set account");
vector_core::db::init_database(npub).expect("init db");
}
fn cycle() {
let guard = vector_core::db::get_db_connection_guard_static().expect("guard");
black_box(&*guard);
}
#[test]
#[ignore = "benchmark, not an assertion"]
fn bench_pool_acquire_release_uncontended() {
setup();
for _ in 0..WARMUP {
cycle();
}
let start = Instant::now();
for _ in 0..ITERS {
cycle();
}
let elapsed = start.elapsed();
println!(
"UNCONTENDED {:>10.1} ns/op ({} iterations in {:?})",
elapsed.as_nanos() as f64 / ITERS as f64,
ITERS,
elapsed
);
}
#[test]
#[ignore = "benchmark, not an assertion"]
fn bench_pool_acquire_release_contended() {
setup();
for _ in 0..WARMUP {
cycle();
}
for threads in [2usize, 4, 8] {
let per_thread = ITERS / threads;
let start = Instant::now();
std::thread::scope(|s| {
for _ in 0..threads {
s.spawn(move || {
for _ in 0..per_thread {
cycle();
}
});
}
});
let elapsed = start.elapsed();
let ops = per_thread * threads;
println!(
"CONTENDED x{:<2} {:>10.1} ns/op ({} ops in {:?})",
threads,
elapsed.as_nanos() as f64 / ops as f64,
ops,
elapsed
);
}
}
#[test]
#[ignore = "benchmark, not an assertion"]
fn bench_scoped_resource_lookup() {
use std::sync::Mutex;
struct BenchKey;
let baseline: &'static Mutex<u64> = Box::leak(Box::new(Mutex::new(0)));
let bump_static = || {
*baseline.lock().unwrap() += 1;
};
let bump_scoped = || {
let cell = vector_core::db::current_session().scoped::<BenchKey, Mutex<u64>>();
*cell.lock().unwrap() += 1;
};
for _ in 0..WARMUP {
bump_static();
bump_scoped();
}
let start = Instant::now();
for _ in 0..ITERS {
bump_static();
}
let flat = start.elapsed();
let start = Instant::now();
for _ in 0..ITERS {
bump_scoped();
}
let via_session = start.elapsed();
println!(
"STATIC LOOKUP {:>10.1} ns/op\nSESSION LOOKUP {:>10.1} ns/op (+{:.1} ns)",
flat.as_nanos() as f64 / ITERS as f64,
via_session.as_nanos() as f64 / ITERS as f64,
(via_session.as_nanos() as f64 - flat.as_nanos() as f64) / ITERS as f64,
);
}