Skip to content

Commit

Permalink
Add max iteration counts, fix clippy stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusGrass committed Jun 12, 2023
1 parent d7d189b commit 9005e0a
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 32 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Expand Up @@ -8,8 +8,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

<!-- next-header -->

## [Unreleased] - ReleaseDate
### Added
### Changed
### Fixed

## [0.3.0] - 2023-06-12

### Added

- `max_iterations` overriding argument to set a hard maximum of iterations.

### Fixed

- Update for new lints and a reformat pass.

## [0.2.0] - 2022-10-07

Expand Down
2 changes: 1 addition & 1 deletion tiny-bench/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "tiny-bench"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
authors = ["Embark <opensource@embark-studios.com>"]
license = "MIT OR Apache-2.0"
Expand Down
14 changes: 13 additions & 1 deletion tiny-bench/benches/benchmark.rs
@@ -1,10 +1,11 @@
use std::time::Duration;
use tiny_bench::black_box;
use tiny_bench::{black_box, BenchmarkConfig};

fn main() {
bench_test_one();
bench_test_two();
bench_test_three();
bench_test_four();
}

fn bench_test_one() {
Expand Down Expand Up @@ -45,3 +46,14 @@ fn bench_test_two() {
fn bench_test_three() {
tiny_bench::bench_labeled("test three, empty", || {});
}

fn bench_test_four() {
tiny_bench::bench_with_configuration_labeled(
"test four, max_it",
&BenchmarkConfig {
max_iterations: Some(5000),
..BenchmarkConfig::default()
},
|| {},
);
}
33 changes: 23 additions & 10 deletions tiny-bench/src/benching/mod.rs
Expand Up @@ -67,11 +67,9 @@ pub fn bench_with_configuration_labeled<T, F: FnMut() -> T>(
let wu = run_warm_up(&mut closure, cfg.warm_up_time);
let mean_execution_time = wu.elapsed.as_nanos() as f64 / wu.iterations as f64;
let sample_size = cfg.num_samples as u64;
let iters = calculate_iterations(mean_execution_time, sample_size, cfg.measurement_time);
let mut total_iters = 0u128;
for count in iters.iter().copied() {
total_iters = total_iters.saturating_add(u128::from(count));
}
let (iters, total_iters) =
calculate_iters_and_total_iters(cfg, mean_execution_time, sample_size);

println!(
"{} mean warm up execution time {} running {} iterations",
wrap_bold_green(label),
Expand All @@ -86,6 +84,23 @@ pub fn bench_with_configuration_labeled<T, F: FnMut() -> T>(
}
}

fn calculate_iters_and_total_iters(
cfg: &BenchmarkConfig,
mean_execution_time: f64,
sample_size: u64,
) -> (Vec<u64>, u128) {
if let Some(max_it) = cfg.max_iterations {
(vec![max_it], u128::from(max_it))
} else {
let iters = calculate_iterations(mean_execution_time, sample_size, cfg.measurement_time);
let mut total_iters = 0u128;
for count in iters.iter().copied() {
total_iters = total_iters.saturating_add(u128::from(count));
}
(iters, total_iters)
}
}

fn run<T, F: FnMut() -> T>(sample_sizes: Vec<u64>, mut closure: F) -> SamplingData {
let times = sample_sizes
.iter()
Expand Down Expand Up @@ -181,11 +196,9 @@ pub fn bench_with_setup_configuration_labeled<T, R, F: FnMut(R) -> T, S: FnMut()
let mean_execution_time = wu.elapsed.as_nanos() as f64 / wu.iterations as f64;

let sample_size = cfg.num_samples as u64;
let iters = calculate_iterations(mean_execution_time, sample_size, cfg.measurement_time);
let mut total_iters = 0u128;
for count in iters.iter().copied() {
total_iters = total_iters.saturating_add(u128::from(count));
}

let (iters, total_iters) =
calculate_iters_and_total_iters(cfg, mean_execution_time, sample_size);
println!(
"{} mean warm up execution time {} running {} iterations",
wrap_bold_green(label),
Expand Down
9 changes: 7 additions & 2 deletions tiny-bench/src/output/analysis/criterion/mod.rs
Expand Up @@ -42,6 +42,11 @@ pub struct BenchmarkConfig {
/// Puts results in target/tiny-bench/label/.. if target can be found.
/// used for comparing previous runs
pub dump_results_to_disk: bool,

/// Sets a hard ceiling on max iterations, overriding the heuristic calculations for iteration
/// count. A rule of thumb; if this is used, the results are unlikely to be statistically
/// significant.
pub max_iterations: Option<u64>,
}

impl Default for BenchmarkConfig {
Expand All @@ -52,6 +57,7 @@ impl Default for BenchmarkConfig {
num_samples: 100,
warm_up_time: Duration::from_secs(3),
dump_results_to_disk: true,
max_iterations: None,
}
}
}
Expand All @@ -73,8 +79,7 @@ pub(crate) fn calculate_iterations(
println!(
"{} You may wish to increase target time to {:.1?} or lower the requested number of samples",
wrap_yellow(&format!(
"Unable to complete {} samples in {:.1?}",
num_samples, target_time
"Unable to complete {num_samples} samples in {target_time:.1?}"
)),
actual_time
);
Expand Down
21 changes: 7 additions & 14 deletions tiny-bench/src/output/disk.rs
Expand Up @@ -73,8 +73,7 @@ fn try_write(
let parent_dir = find_or_create_result_parent_dir(label)?;
std::fs::create_dir_all(&parent_dir).map_err(|e| {
Error::new(format!(
"Failed to create output directory {:?}, cause {e}, will not write results",
parent_dir
"Failed to create output directory {parent_dir:?}, cause {e}, will not write results"
))
})?;

Expand All @@ -83,17 +82,14 @@ fn try_write(
let old_file = parent_dir.join(old_file_name);
if let Err(e) = std::fs::rename(&latest_persisted, &old_file) {
println!(
"{} from {:?} to {:?}, cause {e}, will try to overwrite.",
wrap_yellow("Failed to move old sample"),
latest_persisted,
old_file
"{} from {latest_persisted:?} to {old_file:?}, cause {e}, will try to overwrite.",
wrap_yellow("Failed to move old sample")
);
}
}
std::fs::write(&latest_persisted, data).map_err(|e| {
Error::new(format!(
"Failed to write benchmark-data to {:?}, cause {e}",
latest_persisted
"Failed to write benchmark-data to {latest_persisted:?}, cause {e}"
))
})
}
Expand All @@ -111,8 +107,7 @@ fn try_read(label: &'static str, current_file_name: &'static str) -> Result<Opti
Err(e) => match e.kind() {
ErrorKind::NotFound => Ok(None),
_ => Err(Error::new(format!(
"Failed to read file at {:?}, cause: {e}",
latest_persisted_path
"Failed to read file at {latest_persisted_path:?}, cause: {e}"
))),
},
}
Expand All @@ -133,8 +128,7 @@ fn find_or_create_result_parent_dir(label: &'static str) -> Result<PathBuf> {
let pb = PathBuf::from(&target);
let target_buf = std::fs::metadata(&pb).map_err(|e| {
Error::new(format!(
"Failed to check metadata for target dir {:?}, cause {e}",
target
"Failed to check metadata for target dir {target:?}, cause {e}"
))
})?;
if !target_buf.is_dir() {
Expand All @@ -148,8 +142,7 @@ fn find_or_create_result_parent_dir(label: &'static str) -> Result<PathBuf> {

std::fs::create_dir_all(&result_parent_dir).map_err(|e| {
Error::new(format!(
"Failed to create output directory {:?}, cause {e}",
result_parent_dir
"Failed to create output directory {result_parent_dir:?}, cause {e}"
))
})?;
Ok(result_parent_dir)
Expand Down
6 changes: 3 additions & 3 deletions tiny-bench/src/output/mod.rs
Expand Up @@ -310,7 +310,7 @@ pub(crate) fn wrap_high_intensity_white(text: &str) -> String {
pub(crate) fn fmt_time(time: f64) -> String {
// Nanos
if time < NANO_LIMIT {
format!("{:.2}ns", time)
format!("{time:.2}ns")
} else if time < MICRO_LIMIT {
format!("{:.2}µs", time / NANO_LIMIT)
} else if time < MILLI_LIMIT {
Expand All @@ -321,12 +321,12 @@ pub(crate) fn fmt_time(time: f64) -> String {
}

fn fmt_change(change: f64) -> String {
format!("{:.4}%", change)
format!("{change:.4}%")
}

pub(crate) fn fmt_num(num: f64) -> String {
if num < NANO_LIMIT {
format!("{:.1}", num)
format!("{num:.1}")
} else if num < MICRO_LIMIT {
format!("{:.1} thousand", num / NANO_LIMIT)
} else if num < MILLI_LIMIT {
Expand Down

0 comments on commit 9005e0a

Please sign in to comment.