mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-11-16 15:58:14 +00:00
fix benches
This commit is contained in:
parent
0aa5f77c5e
commit
8ae208b9f0
6 changed files with 140 additions and 357 deletions
|
@ -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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&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::<Outputs>(&tx_rw).unwrap();
|
||||
|
|
|
@ -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::<Outputs>(&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::<Outputs>(&tx_rw).unwrap();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
//! TODO
|
||||
|
||||
#![expect(unused_crate_dependencies)]
|
||||
|
||||
mod db;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
//! TODO
|
||||
|
||||
#![allow(unused_crate_dependencies, reason = "used in benchmarks")]
|
||||
|
||||
mod constants;
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue