diff --git a/Cargo.lock b/Cargo.lock index b57cfa87..1cb95cc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -501,6 +501,7 @@ dependencies = [ "criterion", "cuprate-cryptonight", "function_name", + "paste", ] [[package]] @@ -545,6 +546,7 @@ dependencies = [ "criterion", "cuprate-json-rpc", "function_name", + "paste", "serde_json", ] diff --git a/criterion/cuprate-blockchain/benches/block.rs b/criterion/cuprate-blockchain/benches/block.rs index 4a2bd885..54f293ac 100644 --- a/criterion/cuprate-blockchain/benches/block.rs +++ b/criterion/cuprate-blockchain/benches/block.rs @@ -31,9 +31,14 @@ criterion_group! { } criterion_main!(benches); +fn group() -> String { + format!("{} (block)", cuprate_criterion_blockchain::GROUP) +} + /// Inner function for benchmarking [`block::add_block`]. #[expect(clippy::significant_drop_tightening)] fn add_block_inner(c: &mut Criterion, function_name: &str, block: &VerifiedBlockInformation) { + let mut c = c.benchmark_group(group()); let env = cuprate_criterion_blockchain::TmpEnv::new(); c.bench_function(function_name, |b| { @@ -74,6 +79,7 @@ fn add_block_v16_tx0(c: &mut Criterion) { /// Inner function for benchmarking [`alt_block::add_alt_block`]. #[expect(clippy::significant_drop_tightening)] fn add_alt_block_inner(c: &mut Criterion, function_name: &str, block: &VerifiedBlockInformation) { + let mut c = c.benchmark_group(group()); let env = cuprate_criterion_blockchain::TmpEnv::new(); // We must have at least 1 block or else `add_alt_block` will panic. diff --git a/criterion/cuprate-blockchain/src/lib.rs b/criterion/cuprate-blockchain/src/lib.rs index 8687f45e..15271db3 100644 --- a/criterion/cuprate-blockchain/src/lib.rs +++ b/criterion/cuprate-blockchain/src/lib.rs @@ -5,3 +5,5 @@ mod tmp_env; pub use blocks::generate_fake_blocks; pub use tmp_env::TmpEnv; + +pub const GROUP: &str = "cuprate_blockchain"; diff --git a/criterion/cuprate-cryptonight/Cargo.toml b/criterion/cuprate-cryptonight/Cargo.toml index 21e4d925..a7c736d6 100644 --- a/criterion/cuprate-cryptonight/Cargo.toml +++ b/criterion/cuprate-cryptonight/Cargo.toml @@ -13,6 +13,7 @@ cuprate-cryptonight = { workspace = true } criterion = { workspace = true } function_name = { workspace = true } +paste = { workspace = true } [[bench]] name = "main" diff --git a/criterion/cuprate-cryptonight/benches/hash.rs b/criterion/cuprate-cryptonight/benches/hash.rs index 13dd9069..1bd21e80 100644 --- a/criterion/cuprate-cryptonight/benches/hash.rs +++ b/criterion/cuprate-cryptonight/benches/hash.rs @@ -4,7 +4,6 @@ use std::time::Duration; use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use function_name::named; use cuprate_cryptonight::{ cryptonight_hash_r, cryptonight_hash_v0, cryptonight_hash_v1, cryptonight_hash_v2, @@ -13,12 +12,8 @@ use cuprate_cryptonight::{ criterion_group! { name = benches; // Criterion suggests that higher measurement time is required for these hash functions. - config = Criterion::default().measurement_time(Duration::from_secs(8)); - targets = - r_8, r_64, r_512, r_4096, r_65536, - v0_8, v0_64, v0_512, v0_4096, v0_65536, - v1_8, v1_64, v1_512, v1_4096, v1_65536, - v2_8, v2_64, v2_512, v2_4096, v2_65536, + config = Criterion::default().measurement_time(Duration::from_secs(30)); + targets = hash, } criterion_main!(benches); @@ -35,12 +30,13 @@ macro_rules! impl_hash_benchmark { $fn_name:ident => ($($input:expr_2021),* $(,)?) ),* $(,)? } - )*) => { - $( + )*) => { paste::paste! { + fn hash(c: &mut Criterion) { + let mut c = c.benchmark_group(format!("{}", cuprate_criterion_cryptonight::GROUP)); + $( - #[named] - fn $fn_name(c: &mut Criterion) { - c.bench_function(function_name!(), |b| { + $( + c.bench_function(stringify!($fn_name), |b| { b.iter(|| { drop( black_box( @@ -51,10 +47,10 @@ macro_rules! impl_hash_benchmark { ); }); }); - } + )* )* - )* - }; + } + }} } impl_hash_benchmark! { diff --git a/criterion/cuprate-cryptonight/src/lib.rs b/criterion/cuprate-cryptonight/src/lib.rs index d8b24aed..4666e7f4 100644 --- a/criterion/cuprate-cryptonight/src/lib.rs +++ b/criterion/cuprate-cryptonight/src/lib.rs @@ -1,2 +1,4 @@ //! Benchmark lib for `cuprate-cryptonight`. #![allow(unused_crate_dependencies, reason = "used in benchmarks")] + +pub const GROUP: &str = "cuprate_cryptonight"; diff --git a/criterion/cuprate-database/benches/db.rs b/criterion/cuprate-database/benches/db.rs index e0d4945d..ff42a82a 100644 --- a/criterion/cuprate-database/benches/db.rs +++ b/criterion/cuprate-database/benches/db.rs @@ -56,6 +56,10 @@ criterion_group! { } criterion_main!(benches); +fn group() -> String { + format!("{} (db)", cuprate_criterion_database::GROUP) +} + //---------------------------------------------------------------------------------------------------- DatabaseRo // Read-only table operations. // This uses `TxRw + TablesMut` briefly to insert values, then @@ -66,6 +70,7 @@ criterion_main!(benches); /// [`DatabaseRo::get`] #[named] fn ro_get(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -81,6 +86,7 @@ fn ro_get(c: &mut Criterion) { /// [`DatabaseRo::len`] #[named] fn ro_len(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -96,6 +102,7 @@ fn ro_len(c: &mut Criterion) { /// [`DatabaseRo::first`] #[named] fn ro_first(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -111,6 +118,7 @@ fn ro_first(c: &mut Criterion) { /// [`DatabaseRo::last`] #[named] fn ro_last(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -126,6 +134,7 @@ fn ro_last(c: &mut Criterion) { /// [`DatabaseRo::is_empty`] #[named] fn ro_is_empty(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -141,6 +150,7 @@ fn ro_is_empty(c: &mut Criterion) { /// [`DatabaseRo::contains`] #[named] fn ro_contains(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -161,6 +171,7 @@ fn ro_contains(c: &mut Criterion) { /// [`DatabaseRw::get`] #[named] fn rw_get(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -176,6 +187,7 @@ fn rw_get(c: &mut Criterion) { /// [`DatabaseRw::len`] #[named] fn rw_len(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -191,6 +203,7 @@ fn rw_len(c: &mut Criterion) { /// [`DatabaseRw::first`] #[named] fn rw_first(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -206,6 +219,7 @@ fn rw_first(c: &mut Criterion) { /// [`DatabaseRw::last`] #[named] fn rw_last(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -221,6 +235,7 @@ fn rw_last(c: &mut Criterion) { /// [`DatabaseRw::is_empty`] #[named] fn rw_is_empty(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -236,6 +251,7 @@ fn rw_is_empty(c: &mut Criterion) { /// [`DatabaseRw::contains`] #[named] fn rw_contains(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -252,6 +268,7 @@ fn rw_contains(c: &mut Criterion) { /// [`DatabaseIter::get_range`] #[named] fn get_range(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value_100(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -270,6 +287,7 @@ fn get_range(c: &mut Criterion) { /// [`DatabaseIter::iter`] #[named] fn iter(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value_100(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -288,6 +306,7 @@ fn iter(c: &mut Criterion) { /// [`DatabaseIter::keys`] #[named] fn keys(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value_100(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -306,6 +325,7 @@ fn keys(c: &mut Criterion) { /// [`DatabaseIter::values`] #[named] fn values(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new().with_key_value_100(); let env_inner = env.env.env_inner(); let tx_ro = env_inner.tx_ro().unwrap(); @@ -325,6 +345,7 @@ fn values(c: &mut Criterion) { /// [`DatabaseRw::put`] #[named] fn put(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -343,6 +364,7 @@ fn put(c: &mut Criterion) { /// [`DatabaseRw::delete`] #[named] fn delete(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -372,6 +394,7 @@ fn delete(c: &mut Criterion) { /// [`DatabaseRw::pop_first`] #[named] fn pop_first(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -401,6 +424,7 @@ fn pop_first(c: &mut Criterion) { /// [`DatabaseRw::pop_last`] #[named] fn pop_last(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -430,6 +454,7 @@ fn pop_last(c: &mut Criterion) { /// [`DatabaseRw::take`] #[named] fn take(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); diff --git a/criterion/cuprate-database/benches/env.rs b/criterion/cuprate-database/benches/env.rs index e7213d06..cdc6fae8 100644 --- a/criterion/cuprate-database/benches/env.rs +++ b/criterion/cuprate-database/benches/env.rs @@ -31,6 +31,10 @@ criterion_group! { } criterion_main!(benches); +fn group() -> String { + format!("{} (env)", cuprate_criterion_database::GROUP) +} + // FIXME: This function is hard to time due to: // - heed errors // - "too many open files" errors @@ -56,6 +60,7 @@ criterion_main!(benches); /// [`Env::env_inner`]. #[named] fn env_inner(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); c.bench_function(function_name!(), |b| { @@ -68,6 +73,7 @@ fn env_inner(c: &mut Criterion) { /// [`EnvInner::tx_ro`]. #[named] fn tx_ro(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); @@ -82,6 +88,7 @@ fn tx_ro(c: &mut Criterion) { /// [`EnvInner::tx_rw`]. #[named] fn tx_rw(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); @@ -96,6 +103,7 @@ fn tx_rw(c: &mut Criterion) { /// [`EnvInner::open_db_ro`]. #[named] fn open_db_ro(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); // `with_key_value()` creates the `Outputs` // table so the `open_db_ro` below doesn't panic. let env = TmpEnv::new().with_key_value(); @@ -112,6 +120,7 @@ fn open_db_ro(c: &mut Criterion) { /// [`EnvInner::open_db_rw`]. #[named] fn open_db_rw(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -126,6 +135,7 @@ fn open_db_rw(c: &mut Criterion) { /// [`EnvInner::create_db`]. #[named] fn create_db(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); let env_inner = env.env.env_inner(); let tx_rw = env_inner.tx_rw().unwrap(); @@ -140,6 +150,7 @@ fn create_db(c: &mut Criterion) { /// [`Env::resize`]. #[named] fn resize(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); // Resize env.by the OS page size. @@ -158,6 +169,7 @@ fn resize(c: &mut Criterion) { /// [`Env::current_map_size`]. #[named] fn current_map_size(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); c.bench_function(function_name!(), |b| { @@ -173,6 +185,7 @@ fn current_map_size(c: &mut Criterion) { /// [`Env::disk_size_bytes`]. #[named] fn disk_size_bytes(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let env = TmpEnv::new(); c.bench_function(function_name!(), |b| { diff --git a/criterion/cuprate-database/benches/storable.rs b/criterion/cuprate-database/benches/storable.rs index e2add7d3..f5f302fa 100644 --- a/criterion/cuprate-database/benches/storable.rs +++ b/criterion/cuprate-database/benches/storable.rs @@ -21,9 +21,14 @@ criterion_group! { } criterion_main!(benches); +fn group() -> String { + format!("{} (storable)", cuprate_criterion_database::GROUP) +} + /// [`PreRctOutputId`] cast as bytes. #[named] fn pre_rct_output_id_as_bytes(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); c.bench_function(function_name!(), |b| { b.iter(|| { black_box(Storable::as_bytes(black_box(&KEY))); @@ -34,6 +39,7 @@ fn pre_rct_output_id_as_bytes(c: &mut Criterion) { /// [`PreRctOutputId`] cast from bytes. #[named] fn pre_rct_output_id_from_bytes(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let bytes = Storable::as_bytes(&KEY); c.bench_function(function_name!(), |b| { @@ -46,6 +52,7 @@ fn pre_rct_output_id_from_bytes(c: &mut Criterion) { /// [`Output`] cast as bytes. #[named] fn output_as_bytes(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); c.bench_function(function_name!(), |b| { b.iter(|| { black_box(Storable::as_bytes(black_box(&VALUE))); @@ -56,6 +63,7 @@ fn output_as_bytes(c: &mut Criterion) { /// [`Output`] cast from bytes. #[named] fn output_from_bytes(c: &mut Criterion) { + let mut c = c.benchmark_group(group()); let bytes = Storable::as_bytes(&VALUE); c.bench_function(function_name!(), |b| { diff --git a/criterion/cuprate-database/src/lib.rs b/criterion/cuprate-database/src/lib.rs index 2c527dcd..7cf1731e 100644 --- a/criterion/cuprate-database/src/lib.rs +++ b/criterion/cuprate-database/src/lib.rs @@ -5,3 +5,5 @@ mod tmp_env; pub use constants::{KEY, VALUE}; pub use tmp_env::TmpEnv; + +pub const GROUP: &str = "cuprate_database"; diff --git a/criterion/cuprate-helper/benches/cast.rs b/criterion/cuprate-helper/benches/cast.rs index 256f43d5..d122ec48 100644 --- a/criterion/cuprate-helper/benches/cast.rs +++ b/criterion/cuprate-helper/benches/cast.rs @@ -8,6 +8,8 @@ use cuprate_helper::cast::{ i32_to_isize, i64_to_isize, isize_to_i64, u32_to_usize, u64_to_usize, usize_to_u64, }; +use cuprate_criterion_helper::GROUP; + criterion_group! { name = benches; config = Criterion::default(); @@ -18,7 +20,9 @@ criterion_main!(benches); /// Benchmark integer casts. #[named] fn integer(c: &mut Criterion) { - c.bench_function(function_name!(), |b| { + let mut g = c.benchmark_group(GROUP); + + g.bench_function(function_name!(), |b| { b.iter(|| { black_box(i32_to_isize(black_box(0))); black_box(i64_to_isize(black_box(0))); @@ -30,7 +34,9 @@ fn integer(c: &mut Criterion) { /// Benchmark unsigned integer casts. #[named] fn unsigned(c: &mut Criterion) { - c.bench_function(function_name!(), |b| { + let mut g = c.benchmark_group(GROUP); + + g.bench_function(function_name!(), |b| { b.iter(|| { black_box(u32_to_usize(black_box(0))); black_box(u64_to_usize(black_box(0))); diff --git a/criterion/cuprate-helper/benches/map.rs b/criterion/cuprate-helper/benches/map.rs index 7b2f3445..247d6ed9 100644 --- a/criterion/cuprate-helper/benches/map.rs +++ b/criterion/cuprate-helper/benches/map.rs @@ -8,6 +8,8 @@ use function_name::named; use cuprate_constants::block::MAX_BLOCK_HEIGHT; use cuprate_helper::map; +use cuprate_criterion_helper::GROUP; + criterion_group! { name = benches; config = Criterion::default(); @@ -22,7 +24,8 @@ criterion_main!(benches); /// Benchmark [`curpate_helper::map::combine_low_high_bits_to_u128`]. #[named] fn combine_low_high_bits_to_u128(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(map::combine_low_high_bits_to_u128(b(0), b(0))); }); @@ -32,7 +35,8 @@ fn combine_low_high_bits_to_u128(c: &mut Criterion) { /// Benchmark [`curpate_helper::map::split_u128_into_low_high_bits`]. #[named] fn split_u128_into_low_high_bits(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(map::split_u128_into_low_high_bits(b(0))); }); @@ -42,7 +46,8 @@ fn split_u128_into_low_high_bits(c: &mut Criterion) { /// Benchmark [`curpate_helper::map::timelock_to_u64`]. #[named] fn timelock_to_u64(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(map::timelock_to_u64(b( monero_serai::transaction::Timelock::None, @@ -60,7 +65,8 @@ fn timelock_to_u64(c: &mut Criterion) { /// Benchmark [`curpate_helper::map::u64_to_timelock`]. #[named] fn u64_to_timelock(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(map::u64_to_timelock(b(0))); b(map::u64_to_timelock(b(MAX_BLOCK_HEIGHT))); diff --git a/criterion/cuprate-helper/benches/num.rs b/criterion/cuprate-helper/benches/num.rs index 07095141..414799de 100644 --- a/criterion/cuprate-helper/benches/num.rs +++ b/criterion/cuprate-helper/benches/num.rs @@ -7,6 +7,8 @@ use function_name::named; use cuprate_helper::num; +use cuprate_criterion_helper::GROUP; + criterion_group! { name = benches; config = Criterion::default(); @@ -21,7 +23,8 @@ criterion_main!(benches); /// Benchmark [`curpate_helper::num::cmp_float`]. #[named] fn cmp_float(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(num::cmp_float(b(0.0), b(0.0))); }); @@ -31,7 +34,8 @@ fn cmp_float(c: &mut Criterion) { /// Benchmark [`curpate_helper::num::cmp_float_nan`]. #[named] fn cmp_float_nan(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(num::cmp_float_nan(b(0.0), b(0.0))); }); @@ -41,7 +45,8 @@ fn cmp_float_nan(c: &mut Criterion) { /// Benchmark [`curpate_helper::num::get_mid`]. #[named] fn get_mid(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(num::get_mid(b(0_u8), b(0_u8))); b(num::get_mid(b(1_i64), b(10_i64))); @@ -54,7 +59,8 @@ fn get_mid(c: &mut Criterion) { /// Benchmark [`curpate_helper::num::median`]. #[named] fn median(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(num::median(b(vec![0_u8, 1, 2, 3, 4, 5]))); b(num::median(b(vec![0.0_f32, 1.0, 2.0, 3.0, 4.0, 5.0]))); diff --git a/criterion/cuprate-helper/benches/tx.rs b/criterion/cuprate-helper/benches/tx.rs index 0b2dc2d0..02792ca4 100644 --- a/criterion/cuprate-helper/benches/tx.rs +++ b/criterion/cuprate-helper/benches/tx.rs @@ -8,6 +8,8 @@ use function_name::named; use cuprate_helper::tx; use cuprate_test_utils::data::{TX_V1_SIG0, TX_V1_SIG2, TX_V2_RCT3}; +use cuprate_criterion_helper::GROUP; + criterion_group! { name = benches; config = Criterion::default(); @@ -18,7 +20,9 @@ criterion_main!(benches); /// Benchmark [`curpate_helper::tx::tx_fee`]. #[named] fn tx_fee(c: &mut Criterion) { - c.bench_function(function_name!(), |bench| { + let mut g = c.benchmark_group(GROUP); + + g.bench_function(function_name!(), |bench| { bench.iter(|| { b(tx::tx_fee(b(&TX_V1_SIG0.tx))); b(tx::tx_fee(b(&TX_V1_SIG2.tx))); diff --git a/criterion/cuprate-helper/src/lib.rs b/criterion/cuprate-helper/src/lib.rs index 5a529588..e59ca2e1 100644 --- a/criterion/cuprate-helper/src/lib.rs +++ b/criterion/cuprate-helper/src/lib.rs @@ -1 +1,3 @@ #![allow(unused_crate_dependencies, reason = "used in benchmarks")] + +pub const GROUP: &str = "cuprate_helper"; diff --git a/criterion/cuprate-json-rpc/Cargo.toml b/criterion/cuprate-json-rpc/Cargo.toml index b7bd1202..9bd0bcbb 100644 --- a/criterion/cuprate-json-rpc/Cargo.toml +++ b/criterion/cuprate-json-rpc/Cargo.toml @@ -13,6 +13,7 @@ cuprate-json-rpc = { workspace = true } criterion = { workspace = true } function_name = { workspace = true } +paste = { workspace = true } serde_json = { workspace = true, features = ["default"] } [[bench]] diff --git a/criterion/cuprate-json-rpc/benches/main.rs b/criterion/cuprate-json-rpc/benches/main.rs index a7249430..578dd8ed 100644 --- a/criterion/cuprate-json-rpc/benches/main.rs +++ b/criterion/cuprate-json-rpc/benches/main.rs @@ -4,5 +4,5 @@ mod response; criterion::criterion_main! { - response::serde, + response::benches, } diff --git a/criterion/cuprate-json-rpc/benches/response.rs b/criterion/cuprate-json-rpc/benches/response.rs index 890958ec..4d74bb51 100644 --- a/criterion/cuprate-json-rpc/benches/response.rs +++ b/criterion/cuprate-json-rpc/benches/response.rs @@ -7,32 +7,17 @@ use serde_json::{from_str, to_string_pretty}; use cuprate_json_rpc::{Id, Response}; +use cuprate_criterion_json_rpc::GROUP; + // `serde` benchmarks on `Response`. // // These are benchmarked as `Response` has a custom serde implementation. criterion_group! { - name = serde; + name = benches; config = Criterion::default(); - targets = - response_from_str_u8, - response_from_str_u64, - response_from_str_string_5_len, - response_from_str_string_10_len, - response_from_str_string_100_len, - response_from_str_string_500_len, - response_to_string_pretty_u8, - response_to_string_pretty_u64, - response_to_string_pretty_string_5_len, - response_to_string_pretty_string_10_len, - response_to_string_pretty_string_100_len, - response_to_string_pretty_string_500_len, - response_from_str_bad_field_1, - response_from_str_bad_field_5, - response_from_str_bad_field_10, - response_from_str_bad_field_100, - response_from_str_missing_field, + targets = response_from_str, response_to_string_pretty, } -criterion_main!(serde); +criterion_main!(benches); /// Generate `from_str` deserialization benchmark functions for [`Response`]. macro_rules! impl_from_str_benchmark { @@ -40,42 +25,42 @@ macro_rules! impl_from_str_benchmark { $( $fn_name:ident => $request_type:ty => $request_string:literal, )* - ) => { - $( - #[named] - fn $fn_name(c: &mut Criterion) { - let request_string = $request_string; + ) => { paste::paste! { + fn response_from_str(c: &mut Criterion) { + let mut group = c.benchmark_group(format!("{GROUP} (response, from_str)")); - c.bench_function(function_name!(), |b| { + $({ + let request_string = $request_string; + group.bench_function(stringify!([<$fn_name>]), |b| { b.iter(|| { let _r = from_str::>( black_box(request_string) ); }); }); - } - )* - }; + })* + } + }}; } impl_from_str_benchmark! { - response_from_str_u8 => u8 => r#"{"jsonrpc":"2.0","id":123,"result":0}"#, - response_from_str_u64 => u64 => r#"{"jsonrpc":"2.0","id":123,"result":0}"#, - response_from_str_string_5_len => String => r#"{"jsonrpc":"2.0","id":123,"result":"hello"}"#, - response_from_str_string_10_len => String => r#"{"jsonrpc":"2.0","id":123,"result":"hellohello"}"#, - response_from_str_string_100_len => String => r#"{"jsonrpc":"2.0","id":123,"result":"helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld"}"#, - response_from_str_string_500_len => String => r#"{"jsonrpc":"2.0","id":123,"result":"helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld"}"#, + u8 => u8 => r#"{"jsonrpc":"2.0","id":123,"result":0}"#, + u64 => u64 => r#"{"jsonrpc":"2.0","id":123,"result":0}"#, + string_5_len => String => r#"{"jsonrpc":"2.0","id":123,"result":"hello"}"#, + string_10_len => String => r#"{"jsonrpc":"2.0","id":123,"result":"hellohello"}"#, + string_100_len => String => r#"{"jsonrpc":"2.0","id":123,"result":"helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld"}"#, + string_500_len => String => r#"{"jsonrpc":"2.0","id":123,"result":"helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld"}"#, // The custom serde currently looks at all fields. // These are for testing the performance if the serde // has to parse through a bunch of unrelated fields. - response_from_str_bad_field_1 => u8 => r#"{"bad_field":0,"jsonrpc":"2.0","id":123,"result":0}"#, - response_from_str_bad_field_5 => u8 => r#"{"bad_field_1":0,"bad_field_2":0,"bad_field_3":0,"bad_field_4":0,"bad_field_5":0,"jsonrpc":"2.0","id":123,"result":0}"#, - response_from_str_bad_field_10 => u8 => r#"{"bad_field_1":0,"bad_field_2":0,"bad_field_3":0,"bad_field_4":0,"bad_field_5":0,"bad_field_6":0,"bad_field_7":0,"bad_field_8":0,"bad_field_9":0,"bad_field_10":0,"jsonrpc":"2.0","id":123,"result":0}"#, - response_from_str_bad_field_100 => u8 => r#"{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"jsonrpc":"2.0","id":123,"result":0}"#, + bad_field_1 => u8 => r#"{"bad_field":0,"jsonrpc":"2.0","id":123,"result":0}"#, + bad_field_5 => u8 => r#"{"bad_field_1":0,"bad_field_2":0,"bad_field_3":0,"bad_field_4":0,"bad_field_5":0,"jsonrpc":"2.0","id":123,"result":0}"#, + bad_field_10 => u8 => r#"{"bad_field_1":0,"bad_field_2":0,"bad_field_3":0,"bad_field_4":0,"bad_field_5":0,"bad_field_6":0,"bad_field_7":0,"bad_field_8":0,"bad_field_9":0,"bad_field_10":0,"jsonrpc":"2.0","id":123,"result":0}"#, + bad_field_100 => u8 => r#"{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"jsonrpc":"2.0","id":123,"result":0}"#, // These are missing the `jsonrpc` field. - response_from_str_missing_field => u8 => r#"{"id":123,"result":0}"#, + missing_field => u8 => r#"{"id":123,"result":0}"#, } /// Generate `to_string_pretty` serialization benchmark functions for [`Response`]. @@ -84,27 +69,27 @@ macro_rules! impl_to_string_pretty_benchmark { $( $fn_name:ident => $request_constructor:expr_2021, )* - ) => { - $( - #[named] - fn $fn_name(c: &mut Criterion) { - let request = $request_constructor; + ) => { paste::paste! { + fn response_to_string_pretty(c: &mut Criterion) { + let mut group = c.benchmark_group(format!("{GROUP} (response, to_string_pretty)")); - c.bench_function(function_name!(), |b| { + $({ + let request = $request_constructor; + group.bench_function(stringify!([<$fn_name>]), |b| { b.iter(|| { let _s = to_string_pretty(black_box(&request)).unwrap(); }); }); - } - )* - }; + })* + } + }}; } impl_to_string_pretty_benchmark! { - response_to_string_pretty_u8 => Response::::ok(Id::Null, 0), - response_to_string_pretty_u64 => Response::::ok(Id::Null, 0), - response_to_string_pretty_string_5_len => Response::ok(Id::Null, String::from("hello")), - response_to_string_pretty_string_10_len => Response::ok(Id::Null, String::from("hellohello")), - response_to_string_pretty_string_100_len => Response::ok(Id::Null, String::from("helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld")), - response_to_string_pretty_string_500_len => Response::ok(Id::Null, String::from("helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld")), + u8 => Response::::ok(Id::Null, 0), + u64 => Response::::ok(Id::Null, 0), + string_5_len => Response::ok(Id::Null, String::from("hello")), + string_10_len => Response::ok(Id::Null, String::from("hellohello")), + string_100_len => Response::ok(Id::Null, String::from("helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld")), + string_500_len => Response::ok(Id::Null, String::from("helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld")), } diff --git a/criterion/cuprate-json-rpc/src/lib.rs b/criterion/cuprate-json-rpc/src/lib.rs index b29887aa..c8f157d6 100644 --- a/criterion/cuprate-json-rpc/src/lib.rs +++ b/criterion/cuprate-json-rpc/src/lib.rs @@ -1,2 +1,4 @@ //! Benchmark lib for `cuprate-json-rpc`. #![allow(unused_crate_dependencies, reason = "used in benchmarks")] + +pub const GROUP: &str = "cuprate_json_rpc"; diff --git a/criterion/cuprate-rpc-types/benches/epee.rs b/criterion/cuprate-rpc-types/benches/epee.rs index 7244eb8b..ab8847a2 100644 --- a/criterion/cuprate-rpc-types/benches/epee.rs +++ b/criterion/cuprate-rpc-types/benches/epee.rs @@ -11,11 +11,20 @@ #![allow(unused_attributes, unused_crate_dependencies)] use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion}; -use function_name::named; use cuprate_epee_encoding::{from_bytes, to_bytes}; use cuprate_rpc_types::bin::GetBlocksRequest; +use cuprate_criterion_rpc_types::GROUP; + +// Enable all the benchmark functions created in this macro. +criterion_group! { + name = benches; + config = Criterion::default(); + targets = epee_from_bytes, epee_to_bytes, +} +criterion_main!(benches); + /// Create [`to_bytes`] and [`from_bytes`] benchmarks for `epee` types. macro_rules! generate_epee_benchmarks { ( @@ -23,48 +32,39 @@ macro_rules! generate_epee_benchmarks { $t:ty ),* $(,)? ) => { paste::paste! { - // Generate the benchmarking functions. - $( - #[named] - fn [](c: &mut Criterion) { + fn epee_from_bytes(c: &mut Criterion) { + let mut group = c.benchmark_group(format!("{GROUP} (epee, from_bytes)")); + + // Generate the benchmarking functions. + $( let bytes = to_bytes($t::default()).unwrap(); // `iter_batched()` is used so the `Default::default()` // is not part of the timings. - c.bench_function(function_name!(), |b| { + group.bench_function(stringify!([<$t:snake>]), |b| { b.iter_batched( || bytes.clone(), |mut bytes| drop(from_bytes::<$t, _>(black_box(&mut bytes)).unwrap()), BatchSize::SmallInput, ); }); - } + )* + } - #[named] - fn [](c: &mut Criterion) { - let t = $t::default(); + fn epee_to_bytes(c: &mut Criterion) { + let mut group = c.benchmark_group(format!("{GROUP} (epee, to_bytes)")); - c.bench_function(function_name!(), |b| { + $( + let t = $t::default(); + group.bench_function(stringify!([<$t:snake>]), |b| { b.iter_batched( || t.clone(), |t| drop(to_bytes(black_box(t)).unwrap()), BatchSize::SmallInput, ); }); - } - )* - - // Enable all the benchmark functions created in this macro. - criterion_group! { - name = benches; - config = Criterion::default(); - targets = - $( - [], - [], )* } - criterion_main!(benches); }}; } diff --git a/criterion/cuprate-rpc-types/benches/serde.rs b/criterion/cuprate-rpc-types/benches/serde.rs index 2f612486..38ccebb6 100644 --- a/criterion/cuprate-rpc-types/benches/serde.rs +++ b/criterion/cuprate-rpc-types/benches/serde.rs @@ -22,6 +22,16 @@ use cuprate_rpc_types::{ misc::TxEntry, }; +use cuprate_criterion_rpc_types::GROUP; + +// Enable all the benchmark functions created in this macro. +criterion_group! { + name = benches; + config = Criterion::default(); + targets = serde_from_str, serde_to_string, +} +criterion_main!(benches); + /// Generate [`from_str`] and [`to_string`] benchmarks for `serde` types. macro_rules! generate_serde_benchmarks { ( @@ -30,45 +40,34 @@ macro_rules! generate_serde_benchmarks { $t:ty => $t_example:expr_2021 ),* $(,)? ) => { paste::paste! { - // Generate the benchmarking functions. - $( - #[named] - fn [](c: &mut Criterion) { - c.bench_function(function_name!(), |b| { + fn serde_from_str(c: &mut Criterion) { + let mut group = c.benchmark_group(format!("{GROUP} (serde, from_str)")); + + // Generate the benchmarking functions. + $( + group.bench_function(stringify!([<$t:snake>]), |b| { b.iter(|| { drop(from_str::<$t>( black_box($t_example) ).unwrap()); }); }); - } + )* + } - #[named] - fn [](c: &mut Criterion) { - let t = $t::default(); + fn serde_to_string(c: &mut Criterion) { + let mut group = c.benchmark_group(format!("{GROUP} (serde, to_string)")); - c.bench_function(function_name!(), |b| { + $( + group.bench_function(stringify!([<$t:snake>]), |b| { b.iter_batched( - || t.clone(), + || $t_example.clone(), |t| drop(to_string(black_box(&t)).unwrap()), BatchSize::SmallInput, ); }); - } - - )* - - // Enable all the benchmark functions created in this macro. - criterion_group! { - name = benches; - config = Criterion::default(); - targets = - $( - [], - [], )* } - criterion_main!(benches); }}; } diff --git a/criterion/cuprate-rpc-types/src/lib.rs b/criterion/cuprate-rpc-types/src/lib.rs index 5a529588..fa348b5b 100644 --- a/criterion/cuprate-rpc-types/src/lib.rs +++ b/criterion/cuprate-rpc-types/src/lib.rs @@ -1 +1,3 @@ #![allow(unused_crate_dependencies, reason = "used in benchmarks")] + +pub const GROUP: &str = "cuprate_rpc_types"; diff --git a/criterion/example/benches/example.rs b/criterion/example/benches/example.rs index 7ea8e9a1..56fbf87f 100644 --- a/criterion/example/benches/example.rs +++ b/criterion/example/benches/example.rs @@ -1,10 +1,13 @@ //! Benchmarks. #![allow(unused_attributes, unused_crate_dependencies)] -use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use criterion::{ + black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, BenchmarkId, + Criterion, Throughput, +}; use function_name::named; -use cuprate_criterion_example::SomeHardToCreateObject; +use cuprate_criterion_example::{SomeHardToCreateObject, GROUP}; // This is how you register criterion benchmarks. criterion_group! { @@ -19,9 +22,11 @@ criterion_main!(benches); /// #[named] fn benchmark_1(c: &mut Criterion) { + let mut group = c.benchmark_group(GROUP); + // It is recommended to use `function_name!()` as a benchmark // identifier instead of manually re-typing the function name. - c.bench_function(function_name!(), |b| { + group.bench_function(function_name!(), |b| { b.iter(|| { black_box(SomeHardToCreateObject::from(1)); }); @@ -31,9 +36,8 @@ fn benchmark_1(c: &mut Criterion) { /// Benchmark a range of inputs. /// /// -#[named] fn benchmark_range(c: &mut Criterion) { - let mut group = c.benchmark_group(function_name!()); + let mut group = c.benchmark_group(GROUP); for i in 0..4 { group.throughput(Throughput::Elements(i)); diff --git a/criterion/example/src/lib.rs b/criterion/example/src/lib.rs index 0f732a47..91a5876a 100644 --- a/criterion/example/src/lib.rs +++ b/criterion/example/src/lib.rs @@ -1,6 +1,9 @@ #![doc = include_str!("../README.md")] // See the README for crate documentation. #![allow(unused_crate_dependencies, reason = "used in benchmarks")] +/// All benchmarks performed using this benchmark group will be grouped together in the final report. +pub const GROUP: &str = "example"; + /// Shared type that all benchmarks can use. #[expect(dead_code)] pub struct SomeHardToCreateObject(u64);