mirror of
https://github.com/hinto-janai/cuprate.git
synced 2025-01-09 04:19:53 +00:00
add benches/criterion/cuprate-blockchain
This commit is contained in:
parent
54354f7e9b
commit
059d0e6105
8 changed files with 214 additions and 0 deletions
15
Cargo.lock
generated
15
Cargo.lock
generated
|
@ -758,6 +758,21 @@ dependencies = [
|
||||||
name = "cuprate-constants"
|
name = "cuprate-constants"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cuprate-criterion-blockchain"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"criterion",
|
||||||
|
"cuprate-blockchain",
|
||||||
|
"cuprate-helper",
|
||||||
|
"cuprate-test-utils",
|
||||||
|
"cuprate-types",
|
||||||
|
"function_name",
|
||||||
|
"rand",
|
||||||
|
"serde_json",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cuprate-criterion-example"
|
name = "cuprate-criterion-example"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
|
|
@ -9,6 +9,7 @@ members = [
|
||||||
"benches/benchmark/example",
|
"benches/benchmark/example",
|
||||||
"benches/criterion/example",
|
"benches/criterion/example",
|
||||||
"benches/criterion/cuprate-json-rpc",
|
"benches/criterion/cuprate-json-rpc",
|
||||||
|
"benches/criterion/cuprate-blockchain",
|
||||||
# Consensus
|
# Consensus
|
||||||
"consensus",
|
"consensus",
|
||||||
"consensus/context",
|
"consensus/context",
|
||||||
|
|
28
benches/criterion/cuprate-blockchain/Cargo.toml
Normal file
28
benches/criterion/cuprate-blockchain/Cargo.toml
Normal file
|
@ -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 = { path = "../../../storage/blockchain" }
|
||||||
|
cuprate-test-utils = { path = "../../../test-utils" }
|
||||||
|
cuprate-types = { path = "../../../types", default-features = false }
|
||||||
|
cuprate-helper = { path = "../../../helper", 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
|
67
benches/criterion/cuprate-blockchain/benches/block.rs
Normal file
67
benches/criterion/cuprate-blockchain/benches/block.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
//! Benchmarks for [`block`] functions.
|
||||||
|
|
||||||
|
#![allow(unused_attributes, unused_crate_dependencies)]
|
||||||
|
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
|
use function_name::named;
|
||||||
|
|
||||||
|
use cuprate_blockchain::{
|
||||||
|
cuprate_database::{Env, EnvInner},
|
||||||
|
ops::block,
|
||||||
|
tables::OpenTables,
|
||||||
|
};
|
||||||
|
use cuprate_test_utils::data::{BLOCK_V16_TX0, BLOCK_V1_TX2, BLOCK_V9_TX3};
|
||||||
|
use cuprate_types::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,
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
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);
|
||||||
|
}
|
7
benches/criterion/cuprate-blockchain/benches/main.rs
Normal file
7
benches/criterion/cuprate-blockchain/benches/main.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#![allow(unused_crate_dependencies)]
|
||||||
|
|
||||||
|
mod block;
|
||||||
|
|
||||||
|
criterion::criterion_main! {
|
||||||
|
block::benches,
|
||||||
|
}
|
36
benches/criterion/cuprate-blockchain/src/blocks.rs
Normal file
36
benches/criterion/cuprate-blockchain/src/blocks.rs
Normal file
|
@ -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
benches/criterion/cuprate-blockchain/src/lib.rs
Normal file
7
benches/criterion/cuprate-blockchain/src/lib.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#![allow(unused_crate_dependencies, reason = "used in benchmarks")]
|
||||||
|
|
||||||
|
mod tmp_env;
|
||||||
|
mod blocks;
|
||||||
|
|
||||||
|
pub use blocks::generate_fake_blocks;
|
||||||
|
pub use tmp_env::TmpEnv;
|
53
benches/criterion/cuprate-blockchain/src/tmp_env.rs
Normal file
53
benches/criterion/cuprate-blockchain/src/tmp_env.rs
Normal file
|
@ -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 }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue