From 8ae208b9f08e95ff48244b132c58d63230a8ef3a Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Tue, 22 Oct 2024 20:36:14 -0400 Subject: [PATCH] fix benches --- .../criterion/cuprate-database/benches/db.rs | 398 ++++-------------- .../criterion/cuprate-database/benches/env.rs | 67 +-- .../cuprate-database/benches/main.rs | 2 - .../cuprate-database/benches/storable.rs | 5 +- benches/criterion/cuprate-database/src/lib.rs | 2 - .../criterion/cuprate-database/src/tmp_env.rs | 23 +- 6 files changed, 140 insertions(+), 357 deletions(-) diff --git a/benches/criterion/cuprate-database/benches/db.rs b/benches/criterion/cuprate-database/benches/db.rs index 45934ff..e0d4945 100644 --- a/benches/criterion/cuprate-database/benches/db.rs +++ b/benches/criterion/cuprate-database/benches/db.rs @@ -4,27 +4,9 @@ //! - [`cuprate_database::DatabaseRo`] //! - [`cuprate_database::DatabaseRw`] //! - [`cuprate_database::DatabaseIter`] -//! -//! There are 2 flavors of (read-only) benchmarks: -//! - Single threaded that uses [`TmpEnv::new`] -//! - Multi threaded that uses [`TmpEnv::new_all_threads`] -//! -//! They benchmark the same thing, just with different -//! amount of threads. This is done as 1 "inner" function -//! that contains the logic and 2 others to setup the [`TmpEnv`] -//! with different amounts of threads, e.g.: -//! - [`ro_get`] (inner benchmark logic) -//! - [`ro_get_single_thread`] (just calls `ro_get` with 1 thread) -//! - [`ro_get_multi_thread`] (just calls `ro_get` with all threads) -//! -//! Writes are single-threaded, so they only use [`TmpEnv::new`]. #![allow(unused_crate_dependencies, unused_attributes)] -#![expect(clippy::significant_drop_tightening, clippy::needless_pass_by_value)] - -// TODO -use cuprate_helper as _; -use tempfile as _; +#![expect(clippy::significant_drop_tightening)] use std::time::Instant; @@ -40,45 +22,30 @@ use cuprate_database::{DatabaseIter, DatabaseRo, DatabaseRw, Env, EnvInner}; use cuprate_criterion_database::{TmpEnv, KEY, VALUE}; criterion_group! { - benches, - + name = benches; + config = Criterion::default(); + targets = // `DatabaseRo` - ro_get_single_thread, - ro_get_multi_thread, - ro_len_single_thread, - ro_len_multi_thread, - ro_first_single_thread, - ro_first_multi_thread, - ro_last_single_thread, - ro_last_multi_thread, - ro_is_empty_single_thread, - ro_is_empty_multi_thread, - ro_contains_single_thread, - ro_contains_multi_thread, + ro_get, + ro_len, + ro_first, + ro_last, + ro_is_empty, + ro_contains, // `DatabaseRo` with a `TxRw` - rw_get_single_thread, - rw_get_multi_thread, - rw_len_single_thread, - rw_len_multi_thread, - rw_first_single_thread, - rw_first_multi_thread, - rw_last_single_thread, - rw_last_multi_thread, - rw_is_empty_single_thread, - rw_is_empty_multi_thread, - rw_contains_single_thread, - rw_contains_multi_thread, + rw_get, + rw_len, + rw_first, + rw_last, + rw_is_empty, + rw_contains, // `DatabaseIter` - get_range_single_thread, - get_range_multi_thread, - iter_single_thread, - iter_multi_thread, - keys_single_thread, - keys_multi_thread, - values_single_thread, - values_multi_thread, + get_range, + iter, + keys, + values, // `DatabaseRw` put, @@ -87,353 +54,210 @@ criterion_group! { pop_last, take, } - criterion_main!(benches); -//---------------------------------------------------------------------------------------------------- DatabaseRo::get +//---------------------------------------------------------------------------------------------------- DatabaseRo // Read-only table operations. // This uses `TxRw + TablesMut` briefly to insert values, then // uses `TxRo + Tables` for the actual operation. // // See further below for using `TxRw + TablesMut` on the same operations. -fn ro_get(env: TmpEnv, name: &'static str, c: &mut Criterion) { +/// [`DatabaseRo::get`] +#[named] +fn ro_get(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { - let _value: Output = table.get(black_box(&KEY)).unwrap(); + let _: Output = table.get(black_box(&KEY)).unwrap(); }); }); } -/// [`DatabaseRo::get`] (single-thread). +/// [`DatabaseRo::len`] #[named] -fn ro_get_single_thread(c: &mut Criterion) { +fn ro_len(c: &mut Criterion) { let env = TmpEnv::new().with_key_value(); - ro_get(env, function_name!(), c); -} - -/// [`DatabaseRo::get`] (multi-thread). -#[named] -fn ro_get_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - ro_get(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRo::len -fn ro_len(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { black_box(table.len()).unwrap(); }); }); } -/// [`DatabaseRo::len`] (single-thread). +/// [`DatabaseRo::first`] #[named] -fn ro_len_single_thread(c: &mut Criterion) { +fn ro_first(c: &mut Criterion) { let env = TmpEnv::new().with_key_value(); - ro_len(env, function_name!(), c); -} - -/// [`DatabaseRo::len`] (multi-thread). -#[named] -fn ro_len_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - ro_len(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRo::first -fn ro_first(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { let (_, _): (PreRctOutputId, Output) = black_box(table.first()).unwrap(); }); }); } -/// [`DatabaseRo::first`] (single-thread). -#[named] -fn ro_first_single_thread(c: &mut Criterion) { - let env = TmpEnv::new().with_key_value(); - ro_first(env, function_name!(), c); -} - -/// [`DatabaseRo::first`] (multi-thread). -#[named] -fn ro_first_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - ro_first(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRo::last /// [`DatabaseRo::last`] -fn ro_last(env: TmpEnv, name: &'static str, c: &mut Criterion) { +#[named] +fn ro_last(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { let (_, _): (PreRctOutputId, Output) = black_box(table.last()).unwrap(); }); }); } -/// [`DatabaseRo::last`] (single-thread). -#[named] -fn ro_last_single_thread(c: &mut Criterion) { - let env = TmpEnv::new().with_key_value(); - ro_last(env, function_name!(), c); -} - -/// [`DatabaseRo::last`] (multi-thread). -#[named] -fn ro_last_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - ro_last(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRo::is_empty /// [`DatabaseRo::is_empty`] -fn ro_is_empty(env: TmpEnv, name: &'static str, c: &mut Criterion) { +#[named] +fn ro_is_empty(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { black_box(table.is_empty()).unwrap(); }); }); } -/// [`DatabaseRo::is_empty`] (single-thread). -#[named] -fn ro_is_empty_single_thread(c: &mut Criterion) { - let env = TmpEnv::new().with_key_value(); - ro_is_empty(env, function_name!(), c); -} - -/// [`DatabaseRo::is_empty`] (multi-thread). -#[named] -fn ro_is_empty_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - ro_is_empty(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRo::contains /// [`DatabaseRo::contains`] -fn ro_contains(env: TmpEnv, name: &'static str, c: &mut Criterion) { +#[named] +fn ro_contains(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { table.contains(black_box(&KEY)).unwrap(); }); }); } -/// [`DatabaseRo::contains`] (single-thread). -#[named] -fn ro_contains_single_thread(c: &mut Criterion) { - let env = TmpEnv::new().with_key_value(); - ro_contains(env, function_name!(), c); -} - -/// [`DatabaseRo::contains`] (multi-thread). -#[named] -fn ro_contains_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - ro_contains(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRw::get +//---------------------------------------------------------------------------------------------------- DatabaseRo (TxRw) // These are the same benchmarks as above, but it uses a // `TxRw` and a `TablesMut` instead to ensure our read/write tables // using read operations perform the same as normal read-only tables. -fn rw_get(env: TmpEnv, name: &'static str, c: &mut Criterion) { +/// [`DatabaseRw::get`] +#[named] +fn rw_get(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); let table = env_inner.open_db_rw::(&tx_rw).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { - let _value: Output = table.get(black_box(&KEY)).unwrap(); + let _: Output = table.get(black_box(&KEY)).unwrap(); }); }); } -/// [`DatabaseRw::get`] (single-thread). +/// [`DatabaseRw::len`] #[named] -fn rw_get_single_thread(c: &mut Criterion) { +fn rw_len(c: &mut Criterion) { let env = TmpEnv::new().with_key_value(); - rw_get(env, function_name!(), c); -} - -/// [`DatabaseRw::get`] (multi-thread). -#[named] -fn rw_get_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - rw_get(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRw::len -fn rw_len(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); let table = env_inner.open_db_rw::(&tx_rw).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { black_box(table.len()).unwrap(); }); }); } -/// [`DatabaseRw::len`] (single-thread). +/// [`DatabaseRw::first`] #[named] -fn rw_len_single_thread(c: &mut Criterion) { +fn rw_first(c: &mut Criterion) { let env = TmpEnv::new().with_key_value(); - rw_len(env, function_name!(), c); -} - -/// [`DatabaseRw::len`] (multi-thread). -#[named] -fn rw_len_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - rw_len(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRw::first -fn rw_first(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); let table = env_inner.open_db_rw::(&tx_rw).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { let (_, _): (PreRctOutputId, Output) = black_box(table.first()).unwrap(); }); }); } -/// [`DatabaseRw::first`] (single-thread). +/// [`DatabaseRw::last`] #[named] -fn rw_first_single_thread(c: &mut Criterion) { +fn rw_last(c: &mut Criterion) { let env = TmpEnv::new().with_key_value(); - rw_first(env, function_name!(), c); -} - -/// [`DatabaseRw::first`] (multi-thread). -#[named] -fn rw_first_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - rw_first(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRw::last -fn rw_last(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); let table = env_inner.open_db_rw::(&tx_rw).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { let (_, _): (PreRctOutputId, Output) = black_box(table.last()).unwrap(); }); }); } -/// [`DatabaseRw::last`] (single-thread). +/// [`DatabaseRw::is_empty`] #[named] -fn rw_last_single_thread(c: &mut Criterion) { +fn rw_is_empty(c: &mut Criterion) { let env = TmpEnv::new().with_key_value(); - rw_last(env, function_name!(), c); -} - -/// [`DatabaseRw::last`] (multi-thread). -#[named] -fn rw_last_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - rw_last(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRw::is_empty -fn rw_is_empty(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); let table = env_inner.open_db_rw::(&tx_rw).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { black_box(table.is_empty()).unwrap(); }); }); } -/// [`DatabaseRw::is_empty`] (single-thread). +/// [`DatabaseRw::contains`] #[named] -fn rw_is_empty_single_thread(c: &mut Criterion) { +fn rw_contains(c: &mut Criterion) { let env = TmpEnv::new().with_key_value(); - rw_is_empty(env, function_name!(), c); -} - -/// [`DatabaseRw::is_empty`] (multi-thread). -#[named] -fn rw_is_empty_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - rw_is_empty(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRw::contains -fn rw_contains(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); let table = env_inner.open_db_rw::(&tx_rw).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { table.contains(black_box(&KEY)).unwrap(); }); }); } -/// [`DatabaseRw::contains`] (single-thread). +//---------------------------------------------------------------------------------------------------- DatabaseIter +/// [`DatabaseIter::get_range`] #[named] -fn rw_contains_single_thread(c: &mut Criterion) { - let env = TmpEnv::new().with_key_value(); - rw_contains(env, function_name!(), c); -} - -/// [`DatabaseRw::contains`] (multi-thread). -#[named] -fn rw_contains_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value(); - rw_contains(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseIter::get_range -fn get_range(env: TmpEnv, name: &'static str, c: &mut Criterion) { +fn get_range(c: &mut Criterion) { + let env = TmpEnv::new().with_key_value_100(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { let range = table.get_range(black_box(..)).unwrap(); for result in range { @@ -443,27 +267,15 @@ fn get_range(env: TmpEnv, name: &'static str, c: &mut Criterion) { }); } -/// [`DatabaseIter::get_range`] (single-thread). +/// [`DatabaseIter::iter`] #[named] -fn get_range_single_thread(c: &mut Criterion) { +fn iter(c: &mut Criterion) { let env = TmpEnv::new().with_key_value_100(); - get_range(env, function_name!(), c); -} - -/// [`DatabaseIter::get_range`] (multi-thread). -#[named] -fn get_range_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value_100(); - get_range(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseIter::iter -fn iter(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { let iter = black_box(table.iter()).unwrap(); for result in iter { @@ -473,28 +285,15 @@ fn iter(env: TmpEnv, name: &'static str, c: &mut Criterion) { }); } -/// [`DatabaseIter::iter`] (single-thread). +/// [`DatabaseIter::keys`] #[named] -fn iter_single_thread(c: &mut Criterion) { +fn keys(c: &mut Criterion) { let env = TmpEnv::new().with_key_value_100(); - iter(env, function_name!(), c); -} - -/// [`DatabaseIter::iter`] (multi-thread). -#[named] -fn iter_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value_100(); - iter(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseIter::keys -/// [`DatabaseRo::keys`] -fn keys(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { let keys = black_box(table.keys()).unwrap(); for result in keys { @@ -504,28 +303,15 @@ fn keys(env: TmpEnv, name: &'static str, c: &mut Criterion) { }); } -/// [`DatabaseIter::keys`] (single-thread). +/// [`DatabaseIter::values`] #[named] -fn keys_single_thread(c: &mut Criterion) { +fn values(c: &mut Criterion) { let env = TmpEnv::new().with_key_value_100(); - keys(env, function_name!(), c); -} - -/// [`DatabaseIter::iter`] (multi-thread). -#[named] -fn keys_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value_100(); - keys(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseIter::values -/// [`DatabaseRo::values`] -fn values(env: TmpEnv, name: &'static str, c: &mut Criterion) { let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); let table = env_inner.open_db_ro::(&tx_ro).unwrap(); - c.bench_function(name, |b| { + c.bench_function(function_name!(), |b| { b.iter(|| { let values = black_box(table.values()).unwrap(); for result in values { @@ -535,21 +321,7 @@ fn values(env: TmpEnv, name: &'static str, c: &mut Criterion) { }); } -/// [`DatabaseIter::values`] (single-thread). -#[named] -fn values_single_thread(c: &mut Criterion) { - let env = TmpEnv::new().with_key_value_100(); - values(env, function_name!(), c); -} - -/// [`DatabaseIter::iter`] (multi-thread). -#[named] -fn values_multi_thread(c: &mut Criterion) { - let env = TmpEnv::new_all_threads().with_key_value_100(); - values(env, function_name!(), c); -} - -//---------------------------------------------------------------------------------------------------- DatabaseRw::put +//---------------------------------------------------------------------------------------------------- DatabaseRw /// [`DatabaseRw::put`] #[named] fn put(c: &mut Criterion) { @@ -568,7 +340,6 @@ fn put(c: &mut Criterion) { }); } -//---------------------------------------------------------------------------------------------------- DatabaseRw::delete /// [`DatabaseRw::delete`] #[named] fn delete(c: &mut Criterion) { @@ -598,7 +369,6 @@ fn delete(c: &mut Criterion) { }); } -//---------------------------------------------------------------------------------------------------- DatabaseRw::pop_first /// [`DatabaseRw::pop_first`] #[named] fn pop_first(c: &mut Criterion) { @@ -628,7 +398,6 @@ fn pop_first(c: &mut Criterion) { }); } -//---------------------------------------------------------------------------------------------------- DatabaseRw::pop_last /// [`DatabaseRw::pop_last`] #[named] fn pop_last(c: &mut Criterion) { @@ -658,11 +427,10 @@ fn pop_last(c: &mut Criterion) { }); } -//---------------------------------------------------------------------------------------------------- DatabaseRw::take /// [`DatabaseRw::take`] #[named] fn take(c: &mut Criterion) { - let env = TmpEnv::new_all_threads(); + let env = TmpEnv::new(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); let mut table = env_inner.open_db_rw::(&tx_rw).unwrap(); diff --git a/benches/criterion/cuprate-database/benches/env.rs b/benches/criterion/cuprate-database/benches/env.rs index 75b8793..e7213d0 100644 --- a/benches/criterion/cuprate-database/benches/env.rs +++ b/benches/criterion/cuprate-database/benches/env.rs @@ -1,19 +1,13 @@ -//! Same as `env.rs` but multi-threaded. -//! TODO: create multi-threaded benchmarks +//! [`Env`] benchmarks. #![allow(unused_crate_dependencies, unused_attributes)] #![expect(clippy::significant_drop_tightening)] -// TODO -use cuprate_helper as _; -use tempfile as _; - use criterion::{black_box, criterion_group, criterion_main, Criterion}; use function_name::named; -use cuprate_blockchain::tables::{OpenTables, Outputs}; +use cuprate_blockchain::tables::Outputs; use cuprate_database::{ - config::ConfigBuilder, resize::{ResizeAlgorithm, PAGE_SIZE}, ConcreteEnv, Env, EnvInner, TxRo, TxRw, }; @@ -21,33 +15,43 @@ use cuprate_database::{ use cuprate_criterion_database::TmpEnv; criterion_group! { - benches, - open, + name = benches; + config = Criterion::default(); + targets = + // open, env_inner, tx_ro, tx_rw, open_db_ro, open_db_rw, + create_db, resize, current_map_size, disk_size_bytes, } criterion_main!(benches); -/// [`Env::open`]. -#[named] -fn open(c: &mut Criterion) { - let tempdir = tempfile::tempdir().unwrap(); - let config = ConfigBuilder::new(tempdir.path().to_path_buf().into()) - .low_power() - .build(); - - c.bench_function(function_name!(), |b| { - b.iter_with_large_drop(|| { - ConcreteEnv::open(config.clone()).unwrap(); - }); - }); -} +// FIXME: This function is hard to time due to: +// - heed errors +// - "too many open files" errors +// +// /// [`Env::open`]. +// #[named] +// fn open(c: &mut Criterion) { +// c.bench_function(function_name!(), |b| { +// b.iter_custom(|_| { +// let tempdir = tempfile::tempdir().unwrap(); +// let config = ConfigBuilder::new(tempdir.path().to_path_buf().into()).build(); +// +// let now = std::time::Instant::now(); +// ConcreteEnv::open(config).unwrap(); +// let elapsed = now.elapsed(); +// +// tempdir.close().unwrap(); +// elapsed +// }); +// }); +// } /// [`Env::env_inner`]. #[named] @@ -115,7 +119,20 @@ fn open_db_rw(c: &mut Criterion) { c.bench_function(function_name!(), |b| { b.iter(|| { env_inner.open_db_rw::(&tx_rw).unwrap(); - env_inner.open_tables_mut(&tx_rw).unwrap(); + }); + }); +} + +/// [`EnvInner::create_db`]. +#[named] +fn create_db(c: &mut Criterion) { + let env = TmpEnv::new(); + let env_inner = env.env.env_inner(); + let tx_rw = env_inner.tx_rw().unwrap(); + + c.bench_function(function_name!(), |b| { + b.iter(|| { + env_inner.create_db::(&tx_rw).unwrap(); }); }); } diff --git a/benches/criterion/cuprate-database/benches/main.rs b/benches/criterion/cuprate-database/benches/main.rs index cd9f360..0dba969 100644 --- a/benches/criterion/cuprate-database/benches/main.rs +++ b/benches/criterion/cuprate-database/benches/main.rs @@ -1,5 +1,3 @@ -//! TODO - #![expect(unused_crate_dependencies)] mod db; diff --git a/benches/criterion/cuprate-database/benches/storable.rs b/benches/criterion/cuprate-database/benches/storable.rs index 60d3263..e2add7d 100644 --- a/benches/criterion/cuprate-database/benches/storable.rs +++ b/benches/criterion/cuprate-database/benches/storable.rs @@ -3,7 +3,6 @@ #![allow(unused_crate_dependencies, unused_attributes)] use criterion::{black_box, criterion_group, criterion_main, Criterion}; - use function_name::named; use cuprate_blockchain::types::{Output, PreRctOutputId}; @@ -12,7 +11,9 @@ use cuprate_database::Storable; use cuprate_criterion_database::{KEY, VALUE}; criterion_group! { - benches, + name = benches; + config = Criterion::default(); + targets = pre_rct_output_id_as_bytes, pre_rct_output_id_from_bytes, output_as_bytes, diff --git a/benches/criterion/cuprate-database/src/lib.rs b/benches/criterion/cuprate-database/src/lib.rs index 8f75f4e..2c527dc 100644 --- a/benches/criterion/cuprate-database/src/lib.rs +++ b/benches/criterion/cuprate-database/src/lib.rs @@ -1,5 +1,3 @@ -//! TODO - #![allow(unused_crate_dependencies, reason = "used in benchmarks")] mod constants; diff --git a/benches/criterion/cuprate-database/src/tmp_env.rs b/benches/criterion/cuprate-database/src/tmp_env.rs index d5d263e..1a05e66 100644 --- a/benches/criterion/cuprate-database/src/tmp_env.rs +++ b/benches/criterion/cuprate-database/src/tmp_env.rs @@ -3,7 +3,9 @@ use tempfile::TempDir; use cuprate_blockchain::tables::Outputs; -use cuprate_database::{config::ConfigBuilder, ConcreteEnv, DatabaseRw, Env, EnvInner, TxRw}; +use cuprate_database::{ + config::ConfigBuilder, resize::PAGE_SIZE, ConcreteEnv, DatabaseRw, Env, EnvInner, TxRw, +}; use crate::constants::{KEY, VALUE}; @@ -33,16 +35,15 @@ impl TmpEnv { let config = ConfigBuilder::new(path).low_power().build(); let env = ConcreteEnv::open(config).unwrap(); - Self { env, tempdir } - } - - /// Same as [`Self::new`] but uses all system threads for the [`Env`]. - #[expect(clippy::missing_panics_doc)] - pub fn new_all_threads() -> Self { - let tempdir = tempfile::tempdir().unwrap(); - let path = tempdir.path().to_path_buf().into(); - let config = ConfigBuilder::new(path).fast().build(); - let env = ConcreteEnv::open(config).unwrap(); + // Resize to a very large map to prevent resize errors. + if ConcreteEnv::MANUAL_RESIZE { + // SAFETY: no write transactions exist yet. + unsafe { + env.env_inner() + .resize(PAGE_SIZE.get() * 1024 * 1024 * 1024) + .unwrap(); + } + } Self { env, tempdir } }