name changes, bin impl
Some checks are pending
Audit / audit (push) Waiting to run
Deny / audit (push) Waiting to run

This commit is contained in:
hinto.janai 2024-10-03 21:36:32 -04:00
parent 39fe790553
commit 7bac741d5f
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
18 changed files with 179 additions and 312 deletions

42
Cargo.lock generated
View file

@ -632,6 +632,27 @@ dependencies = [
"tokio",
]
[[package]]
name = "cuprate-benchmark"
version = "0.0.0"
dependencies = [
"cfg-if",
"cuprate-benchmark-example",
"cuprate-benchmark-lib",
"cuprate-database",
]
[[package]]
name = "cuprate-benchmark-example"
version = "0.0.0"
dependencies = [
"cuprate-benchmark-lib",
]
[[package]]
name = "cuprate-benchmark-lib"
version = "0.0.0"
[[package]]
name = "cuprate-blockchain"
version = "0.0.0"
@ -821,27 +842,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "cuprate-harness"
version = "0.0.0"
dependencies = [
"cfg-if",
"cuprate-database",
"cuprate-harness-lib",
"cuprate-harness-test",
]
[[package]]
name = "cuprate-harness-lib"
version = "0.0.0"
[[package]]
name = "cuprate-harness-test"
version = "0.0.0"
dependencies = [
"cuprate-harness-lib",
]
[[package]]
name = "cuprate-helper"
version = "0.1.0"

View file

@ -4,9 +4,9 @@ members = [
# Binaries
"binaries/cuprated",
# Benchmarks
"benches/harness",
"benches/harness/lib",
"benches/harness/harness-test",
"benches/benchmark/bin",
"benches/benchmark/lib",
"benches/benchmark/example",
"benches/criterion/cuprate-json-rpc",
# Consensus
"consensus",

View file

@ -0,0 +1,28 @@
[package]
name = "cuprate-benchmark"
version = "0.0.0"
edition = "2021"
description = "Cuprate's benchmarking binary"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/benchmark/bin"
keywords = ["cuprate", "benchmarking", "binary"]
[features]
default = ["example"]
example = ["dep:cuprate-benchmark-example"]
database = ["dep:cuprate-database"]
[dependencies]
cuprate-benchmark-lib = { path = "../lib" }
cuprate-benchmark-example = { path = "../example", optional = true }
cuprate-database = { path = "../../../storage/database", optional = true }
cfg-if = { workspace = true }
# serde = { workspace = true, features = ["derive"] }
# serde_json = { workspace = true, features = ["std"] }
[dev-dependencies]
[lints]
workspace = true

View file

@ -0,0 +1 @@
## `cuprate-benchmark`

View file

@ -0,0 +1,66 @@
#![doc = include_str!("../README.md")]
#![allow(
unused_crate_dependencies,
reason = "this crate imports many potentially unused dependencies"
)]
use std::{collections::HashMap, io::Write};
use cfg_if::cfg_if;
use cuprate_benchmark_lib::Benchmark;
fn main() {
let mut timings = HashMap::new();
cfg_if! {
if #[cfg(not(any(feature = "database", feature = "example")))] {
compile_error!("[cuprate_benchmark]: no feature specified. Use `--features $BENCHMARK_FEATURE` when building.");
}
}
cfg_if! {
if #[cfg(feature = "database")] {
run_benchmark::<cuprate_benchmark_database::Benchmark>(&mut timings);
}
}
cfg_if! {
if #[cfg(feature = "example")] {
run_benchmark::<cuprate_benchmark_example::Example>(&mut timings);
}
}
print_timings(&timings);
}
fn run_benchmark<B: Benchmark>(timings: &mut HashMap<&'static str, f32>) {
let name = std::any::type_name::<B>();
print!("{name:>34} ... ");
std::io::stdout().flush().unwrap();
let input = B::SETUP();
let now = std::time::Instant::now();
B::MAIN(input);
let time = now.elapsed().as_secs_f32();
println!("{time}");
assert!(
timings.insert(name, time).is_none(),
"[cuprate_benchmark]: there were 2 benchmarks with the same name - this collides the final output: {name}",
);
}
fn print_timings(timings: &HashMap<&'static str, f32>) {
let mut s = String::new();
s.push_str("| Benchmark | Time (seconds) |\n");
s.push_str("|------------------------------------|----------------|");
#[expect(clippy::iter_over_hash_type)]
for (k, v) in timings {
s += &format!("\n| {k:<34} | {v:<14} |");
}
println!("\n{s}");
}

View file

@ -0,0 +1,17 @@
[package]
name = "cuprate-benchmark-example"
version = "0.0.0"
edition = "2021"
description = "Example showcasing Cuprate's benchmarking harness"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/benchmark/example"
keywords = ["cuprate", "benchmarking", "example"]
[dependencies]
cuprate-benchmark-lib = { path = "../lib" }
[dev-dependencies]
[lints]
workspace = true

View file

@ -0,0 +1 @@
## `cuprate-benchmark-example`

View file

@ -0,0 +1,10 @@
#![doc = include_str!("../README.md")]
/// TODO
pub struct Example;
impl cuprate_benchmark_lib::Benchmark for Example {
type Input = ();
const SETUP: fn() -> Self::Input = || {};
const MAIN: fn(Self::Input) = |()| {};
}

View file

@ -0,0 +1,18 @@
[package]
name = "cuprate-benchmark-lib"
version = "0.0.0"
edition = "2021"
description = "Cuprate's benchmarking library"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/benchmark/lib"
keywords = ["cuprate", "benchmarking", "library"]
[features]
[dependencies]
[dev-dependencies]
[lints]
workspace = true

View file

@ -0,0 +1 @@
## `cuprate-benchmark-lib`

View file

@ -1,16 +1,21 @@
//! TODO
//---------------------------------------------------------------------------------------------------- Use
//---------------------------------------------------------------------------------------------------- trait Benchmark
/// A benchmarking function and its inputs.
pub trait Benchmark {
/// Input to the main benchmarking function.
///
/// This is passed to [`Self::MAIN`].
type Input;
/// Setup function to generate the input.
///
/// This function is not timed.
const SETUP: fn() -> Self::Input;
/// The main function to benchmark.
///
/// The start of the timer begins right before
/// this function is called and ends after the
/// function returns.
const MAIN: fn(Self::Input);
}

View file

@ -0,0 +1,5 @@
#![doc = include_str!("../README.md")]
mod benchmark;
pub use benchmark::Benchmark;

View file

@ -1,23 +0,0 @@
[package]
name = "cuprate-harness"
version = "0.0.0"
edition = "2021"
description = "Cuprate's benchmarking harness binary"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/harness"
keywords = ["cuprate", "benchmarking", "harness", "binary"]
[features]
default = ["test"]
test = ["dep:cuprate-harness-test"]
database = ["dep:cuprate-database"]
[dependencies]
cuprate-harness-lib = { path = "lib" }
cuprate-harness-test = { path = "harness-test", optional = true }
cuprate-database = { path = "../../storage/database", optional = true }
cfg-if = { workspace = true }
[dev-dependencies]

View file

@ -1,14 +0,0 @@
[package]
name = "cuprate-harness-test"
version = "0.0.0"
edition = "2021"
description = "Test for Cuprate's benchmarking harness"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/macro/harness-test"
keywords = ["cuprate", "benchmarking", "harness", "test"]
[dependencies]
cuprate-harness-lib = { path = "../lib" }
[dev-dependencies]

View file

@ -1,16 +0,0 @@
//! TODO
/// TODO
pub struct BenchmarkHarnessTest;
// TODO
impl cuprate_harness_lib::Benchmark for BenchmarkHarnessTest {
/// TODO
type Input = ();
/// TODO
const SETUP: fn() -> Self::Input = || {};
/// TODO
const MAIN: fn(Self::Input) = |_| {};
}

View file

@ -1,15 +0,0 @@
[package]
name = "cuprate-harness-lib"
version = "0.0.0"
edition = "2021"
description = "Cuprate's benchmarking harness library"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/benches/harness/core"
keywords = ["cuprate", "benchmarking", "harness", "library"]
[features]
[dependencies]
[dev-dependencies]

View file

@ -1,97 +0,0 @@
//! TODO
//---------------------------------------------------------------------------------------------------- Lints
// Forbid lints.
// Our code, and code generated (e.g macros) cannot overrule these.
#![forbid(
// `unsafe` is allowed but it _must_ be
// commented with `SAFETY: reason`.
clippy::undocumented_unsafe_blocks,
// Never.
unused_unsafe,
redundant_semicolons,
unused_allocation,
coherence_leak_check,
while_true,
clippy::missing_docs_in_private_items,
// Maybe can be put into `#[deny]`.
unconditional_recursion,
for_loops_over_fallibles,
unused_braces,
unused_labels,
keyword_idents,
non_ascii_idents,
variant_size_differences,
single_use_lifetimes,
// Probably can be put into `#[deny]`.
future_incompatible,
let_underscore,
break_with_label_and_loop,
duplicate_macro_attributes,
exported_private_dependencies,
large_assignments,
overlapping_range_endpoints,
semicolon_in_expressions_from_macros,
noop_method_call,
unreachable_pub,
)]
// Deny lints.
// Some of these are `#[allow]`'ed on a per-case basis.
#![deny(
clippy::all,
clippy::correctness,
clippy::suspicious,
clippy::style,
clippy::complexity,
clippy::perf,
clippy::pedantic,
clippy::nursery,
clippy::cargo,
unused_doc_comments,
unused_mut,
missing_docs,
deprecated,
unused_comparisons,
nonstandard_style
)]
#![allow(
// FIXME: this lint affects crates outside of
// `database/` for some reason, allow for now.
clippy::cargo_common_metadata,
// FIXME: adding `#[must_use]` onto everything
// might just be more annoying than useful...
// although it is sometimes nice.
clippy::must_use_candidate,
// FIXME: good lint but too many false positives
// with our `Env` + `RwLock` setup.
clippy::significant_drop_tightening,
// FIXME: good lint but is less clear in most cases.
clippy::items_after_statements,
clippy::module_name_repetitions,
clippy::module_inception,
clippy::redundant_pub_crate,
clippy::option_if_let_else,
)]
// Allow some lints when running in debug mode.
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
// Allow some lints in tests.
#![cfg_attr(
test,
allow(
clippy::cognitive_complexity,
clippy::needless_pass_by_value,
clippy::cast_possible_truncation,
clippy::too_many_lines
)
)]
//---------------------------------------------------------------------------------------------------- Modules
mod benchmark;
pub use benchmark::Benchmark;

View file

@ -1,120 +0,0 @@
//! TODO
//---------------------------------------------------------------------------------------------------- Lints
// Forbid lints.
// Our code, and code generated (e.g macros) cannot overrule these.
#![forbid(
// `unsafe` is allowed but it _must_ be
// commented with `SAFETY: reason`.
clippy::undocumented_unsafe_blocks,
// Never.
unused_unsafe,
redundant_semicolons,
unused_allocation,
coherence_leak_check,
while_true,
clippy::missing_docs_in_private_items,
// Maybe can be put into `#[deny]`.
unconditional_recursion,
for_loops_over_fallibles,
unused_braces,
unused_labels,
keyword_idents,
non_ascii_idents,
variant_size_differences,
single_use_lifetimes,
// Probably can be put into `#[deny]`.
future_incompatible,
let_underscore,
break_with_label_and_loop,
duplicate_macro_attributes,
exported_private_dependencies,
large_assignments,
overlapping_range_endpoints,
semicolon_in_expressions_from_macros,
noop_method_call,
unreachable_pub,
)]
// Deny lints.
// Some of these are `#[allow]`'ed on a per-case basis.
#![deny(
clippy::all,
clippy::correctness,
clippy::suspicious,
clippy::style,
clippy::complexity,
clippy::perf,
clippy::pedantic,
clippy::nursery,
clippy::cargo,
unused_doc_comments,
unused_mut,
missing_docs,
deprecated,
unused_comparisons,
nonstandard_style
)]
#![allow(
// FIXME: this lint affects crates outside of
// `database/` for some reason, allow for now.
clippy::cargo_common_metadata,
// FIXME: adding `#[must_use]` onto everything
// might just be more annoying than useful...
// although it is sometimes nice.
clippy::must_use_candidate,
// FIXME: good lint but too many false positives
// with our `Env` + `RwLock` setup.
clippy::significant_drop_tightening,
// FIXME: good lint but is less clear in most cases.
clippy::items_after_statements,
clippy::module_name_repetitions,
clippy::module_inception,
clippy::redundant_pub_crate,
clippy::option_if_let_else,
)]
// Allow some lints when running in debug mode.
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
// Allow some lints in tests.
#![cfg_attr(
test,
allow(
clippy::cognitive_complexity,
clippy::needless_pass_by_value,
clippy::cast_possible_truncation,
clippy::too_many_lines
)
)]
//---------------------------------------------------------------------------------------------------- Modules
cfg_if::cfg_if! {
if #[cfg(feature = "database")] {
use cuprate_harness_database::BenchmarkDatabase as B;
} else if #[cfg(feature = "test")] {
use cuprate_harness_test::BenchmarkHarnessTest as B;
} else {
compile_error!("cuprate_harness: no feature specified. Use `--features $YOUR_CRATE_BENCHMARK_NAME` when building.");
}
}
//---------------------------------------------------------------------------------------------------- Main
use cuprate_harness_lib::Benchmark;
//---------------------------------------------------------------------------------------------------- Main
#[allow(clippy::let_unit_value)]
fn main() {
let input = B::SETUP();
let name = std::any::type_name::<B>();
println!("[Cuprate Harness] {name}");
let now = std::time::Instant::now();
B::MAIN(input);
println!("{}", now.elapsed().as_secs_f32());
}