Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

criterion: initial benchmarks #352

Closed
wants to merge 48 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
04e1f10
add readme
hinto-janai Jun 26, 2024
b538272
readme, basic examples
hinto-janai Jun 26, 2024
39fe790
Merge branch 'main' into benches
hinto-janai Oct 4, 2024
7bac741
name changes, bin impl
hinto-janai Oct 4, 2024
24d176f
example, docs
hinto-janai Oct 4, 2024
6525307
book
hinto-janai Oct 8, 2024
897396e
Merge branch 'main' into benches
hinto-janai Oct 8, 2024
185c2ee
add `cuprate-criterion-example`
hinto-janai Oct 8, 2024
9a0b613
docs, tracing
hinto-janai Oct 9, 2024
8c9d159
fix clippy
hinto-janai Oct 9, 2024
828cbba
docs
hinto-janai Oct 9, 2024
fe6c395
Merge branch 'main' into benches
hinto-janai Oct 9, 2024
cab2011
lib readme
hinto-janai Oct 9, 2024
eb617b3
json-rpc benchmarks
hinto-janai Oct 9, 2024
2e3e36c
add to crates.md
hinto-janai Oct 9, 2024
1c462e3
add `fixme`
hinto-janai Oct 10, 2024
e1a6f82
add `benches/criterion/cuprate-helper`
hinto-janai Oct 19, 2024
7a94952
copy #98
hinto-janai Oct 21, 2024
1cada33
fix `cargo b` failing
hinto-janai Oct 22, 2024
da3417f
changes
hinto-janai Oct 22, 2024
0aa5f77
fix cargo
hinto-janai Oct 22, 2024
8ae208b
fix benches
hinto-janai Oct 23, 2024
d89840e
add `benches/criterion/cuprate-cryptonight`
hinto-janai Oct 24, 2024
615cef9
storage: remove todo `println!()`
hinto-janai Oct 24, 2024
a5ba544
add `benches/criterion/cuprate-rpc-types`
hinto-janai Oct 25, 2024
d2b30c1
add benches
hinto-janai Oct 26, 2024
725b532
fix json
hinto-janai Oct 26, 2024
54354f7
Merge branch 'main' into benches
hinto-janai Oct 26, 2024
636e485
add to `typos.toml`
hinto-janai Oct 26, 2024
e6f55f0
Merge branch 'benches' into rpc-types-benches
hinto-janai Oct 26, 2024
0c2b338
Merge branch 'benches' into cryptonight-bench
hinto-janai Oct 26, 2024
bacda5f
Merge branch 'benches' into db-bench
hinto-janai Oct 26, 2024
9ea41c3
Merge branch 'main' into helper-bench
hinto-janai Oct 26, 2024
c8c1c2e
Merge branch 'benches' into helper-bench
hinto-janai Oct 26, 2024
705cd7e
clippy
hinto-janai Oct 26, 2024
059d0e6
add `benches/criterion/cuprate-blockchain`
hinto-janai Oct 31, 2024
e5db01a
fmt
hinto-janai Oct 31, 2024
1cf86ed
alt_block
hinto-janai Oct 31, 2024
f65ff1b
fix alt_block height
hinto-janai Oct 31, 2024
9ba17f8
Merge branch 'main' into helper-bench
hinto-janai Nov 28, 2024
3f2fc0e
Merge branch 'db-bench' into criterion
hinto-janai Nov 28, 2024
fe4f4ee
Merge branch 'cryptonight-bench' into criterion
hinto-janai Nov 28, 2024
867ef3f
Merge branch 'rpc-types-benches' into criterion
hinto-janai Nov 28, 2024
7b31745
Merge branch 'blockchain-benches' into criterion
hinto-janai Nov 28, 2024
7e00501
cargo.toml fixes
hinto-janai Nov 28, 2024
f15f08b
1.83 clippy fix
hinto-janai Nov 28, 2024
f998f61
Merge branch 'main' into criterion
hinto-janai Nov 28, 2024
d0ca28b
clippy fix
hinto-janai Nov 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
631 changes: 444 additions & 187 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ members = [
"benches/benchmark/example",
"benches/criterion/example",
"benches/criterion/cuprate-json-rpc",
"benches/criterion/cuprate-helper",
"benches/criterion/cuprate-database",
"benches/criterion/cuprate-cryptonight",
"benches/criterion/cuprate-rpc-types",
"benches/criterion/cuprate-blockchain",

# Consensus
"consensus",
Expand Down
2 changes: 1 addition & 1 deletion benches/benchmark/bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ tracing-subscriber = { workspace = true, features = ["fmt", "std", "env-filter"]
[dev-dependencies]

[lints]
workspace = true
workspace = true
28 changes: 28 additions & 0 deletions benches/criterion/cuprate-blockchain/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "cuprate-criterion-blockchain"
version = "0.0.0"
edition = "2021"
description = "Criterion benchmarking for cuprate-blockchain"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/criterion/cuprate-blockchain"
keywords = ["cuprate", "blockchain", "criterion", "benchmark"]

[dependencies]
cuprate-blockchain = { workspace = true }
cuprate-test-utils = { workspace = true }
cuprate-types = { workspace = true, default-features = false }
cuprate-helper = { workspace = true, features = ["cast"] }

criterion = { workspace = true }
function_name = { workspace = true }
serde_json = { workspace = true, features = ["default"] }
tempfile = { workspace = true }
rand = { workspace = true }

[[bench]]
name = "main"
harness = false

[lints]
workspace = true
140 changes: 140 additions & 0 deletions benches/criterion/cuprate-blockchain/benches/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//! Benchmarks for [`block`] and [`alt_block`] functions.

#![allow(unused_attributes, unused_crate_dependencies)]

use std::{num::NonZeroU64, time::Instant};

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use cuprate_helper::cast::usize_to_u64;
use function_name::named;

use cuprate_blockchain::{
cuprate_database::{Env, EnvInner},
ops::{alt_block, block},
tables::OpenTables,
};
use cuprate_test_utils::data::{BLOCK_V16_TX0, BLOCK_V1_TX2, BLOCK_V9_TX3};
use cuprate_types::{AltBlockInformation, ChainId, VerifiedBlockInformation};

use cuprate_criterion_blockchain::generate_fake_blocks;

criterion_group! {
name = benches;
config = Criterion::default();
targets =
add_block_v1_tx2,
add_block_v9_tx3,
add_block_v16_tx0,
add_alt_block_v1_tx2,
add_alt_block_v9_tx3,
add_alt_block_v16_tx0,
}
criterion_main!(benches);

/// 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 env = cuprate_criterion_blockchain::TmpEnv::new();

c.bench_function(function_name, |b| {
// We use `iter_custom` because we need to generate an
// appropriate amount of blocks and only time the `add_block`.
b.iter_custom(|count| {
let blocks = black_box(generate_fake_blocks(block, count));

let env_inner = env.env.env_inner();
let tx_rw = env_inner.tx_rw().unwrap();
let mut tables = env_inner.open_tables_mut(&tx_rw).unwrap();

let start = Instant::now();
for block in &blocks {
let block = black_box(block);
black_box(block::add_block(block, &mut tables)).unwrap();
}
start.elapsed()
});
});
}

#[named]
fn add_block_v1_tx2(c: &mut Criterion) {
add_block_inner(c, function_name!(), &BLOCK_V1_TX2);
}

#[named]
fn add_block_v9_tx3(c: &mut Criterion) {
add_block_inner(c, function_name!(), &BLOCK_V9_TX3);
}

#[named]
fn add_block_v16_tx0(c: &mut Criterion) {
add_block_inner(c, function_name!(), &BLOCK_V16_TX0);
}

/// 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 env = cuprate_criterion_blockchain::TmpEnv::new();

// We must have at least 1 block or else `add_alt_block` will panic.
{
let env_inner = env.env.env_inner();
let tx_rw = env_inner.tx_rw().unwrap();
let mut tables = env_inner.open_tables_mut(&tx_rw).unwrap();

let mut block = BLOCK_V1_TX2.clone();
block.height = 0;

block::add_block(&block, &mut tables).unwrap();
}

c.bench_function(function_name, |b| {
// We use `iter_custom` because we need to generate an
// appropriate amount of blocks and only time the `add_block`.
b.iter_custom(|count| {
// Map the block to a fake alt block.
let blocks = generate_fake_blocks(block, count)
.into_iter()
.enumerate()
.map(|(i, b)| AltBlockInformation {
block: b.block,
block_blob: b.block_blob,
txs: b.txs,
block_hash: b.block_hash,
pow_hash: b.pow_hash,
height: b.height + 1,
weight: b.weight,
long_term_weight: b.long_term_weight,
cumulative_difficulty: b.cumulative_difficulty,
chain_id: ChainId(NonZeroU64::new(usize_to_u64(i) + 1).unwrap()),
})
.collect::<Vec<AltBlockInformation>>();

let env_inner = env.env.env_inner();
let tx_rw = env_inner.tx_rw().unwrap();
let mut tables = env_inner.open_tables_mut(&tx_rw).unwrap();

let start = Instant::now();
for block in &blocks {
let block = black_box(block);
black_box(alt_block::add_alt_block(block, &mut tables)).unwrap();
}
start.elapsed()
});
});
}

#[named]
fn add_alt_block_v1_tx2(c: &mut Criterion) {
add_alt_block_inner(c, function_name!(), &BLOCK_V1_TX2);
}

#[named]
fn add_alt_block_v9_tx3(c: &mut Criterion) {
add_alt_block_inner(c, function_name!(), &BLOCK_V9_TX3);
}

#[named]
fn add_alt_block_v16_tx0(c: &mut Criterion) {
add_alt_block_inner(c, function_name!(), &BLOCK_V16_TX0);
}
7 changes: 7 additions & 0 deletions benches/criterion/cuprate-blockchain/benches/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![allow(unused_crate_dependencies)]

mod block;

criterion::criterion_main! {
block::benches,
}
36 changes: 36 additions & 0 deletions benches/criterion/cuprate-blockchain/src/blocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use rand::Rng;

use cuprate_helper::cast::u64_to_usize;
use cuprate_types::VerifiedBlockInformation;

/// Generate fake [`VerifiedBlockInformation`]s.
///
/// This function generates fake blocks,
/// cloning the `base` block `count` amount of times,
/// starting at height `0` and sequentially incrementing,
/// i.e. block height `{0,1,2,...}`.
///
/// Each block has a random [`VerifiedBlockInformation::block_hash`].
///
/// # Hack
/// This is used for these benchmarks because
/// [`cuprate_blockchain::ops::block::add_block`]
/// asserts that blocks with non-sequential heights cannot be added.
/// To get around this, we manually edit the block heights.
///
/// The hash must also be faked as
/// [`cuprate_blockchain::ops::blockchain::chain_height`]
/// which is used for an [`assert`] relies on the `hash -> height` table.
pub fn generate_fake_blocks(
base: &VerifiedBlockInformation,
count: u64,
) -> Vec<VerifiedBlockInformation> {
(0..count)
.map(|height| {
let mut block = base.clone();
block.height = u64_to_usize(height);
block.block_hash = rand::thread_rng().r#gen();
block
})
.collect()
}
7 changes: 7 additions & 0 deletions benches/criterion/cuprate-blockchain/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![allow(unused_crate_dependencies, reason = "used in benchmarks")]

mod blocks;
mod tmp_env;

pub use blocks::generate_fake_blocks;
pub use tmp_env::TmpEnv;
53 changes: 53 additions & 0 deletions benches/criterion/cuprate-blockchain/src/tmp_env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//! An [`Env`] inside a [`TempDir`].

use tempfile::TempDir;

use cuprate_blockchain::{
config::ReaderThreads,
cuprate_database::{config::ConfigBuilder, resize::PAGE_SIZE, ConcreteEnv, Env},
};

/// A temporary in-memory [`Env`].
///
/// This is a [`ConcreteEnv`] that uses [`TempDir`] as the
/// backing file location - this is an in-memory file on Linux.
pub struct TmpEnv {
pub env: ConcreteEnv,
pub tempdir: TempDir,
}

impl Default for TmpEnv {
fn default() -> Self {
Self::new()
}
}

impl TmpEnv {
/// Create an `Env` in a temporary directory.
///
/// The directory is automatically removed after the [`TempDir`] is dropped.
#[expect(clippy::missing_panics_doc)]
pub fn new() -> Self {
let tempdir = tempfile::tempdir().unwrap();
let path = tempdir.path().to_path_buf().into();
let db_config = ConfigBuilder::new(path).low_power().build();
let reader_threads = ReaderThreads::One;
let config = cuprate_blockchain::config::Config {
db_config,
reader_threads,
};
let env = cuprate_blockchain::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 }
}
}
22 changes: 22 additions & 0 deletions benches/criterion/cuprate-cryptonight/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "cuprate-criterion-cryptonight"
version = "0.0.0"
edition = "2021"
description = "Criterion benchmarking for cuprate-cryptonight"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/criterion/cuprate-cryptonight"
keywords = ["cuprate", "cryptonight", "criterion", "benchmark"]

[dependencies]
cuprate-cryptonight = { workspace = true }

criterion = { workspace = true }
function_name = { workspace = true }

[[bench]]
name = "main"
harness = false

[lints]
workspace = true
Loading
Loading