1use std::time::Duration;
2
3use crate::{BenchmarkContext, LoopControl, SubBenchResult};
4
5pub fn iter(
6 ctx: &BenchmarkContext,
7 name: &str,
8 throughput_unit: &str,
9 throughput_count_per_iteration: u32,
10 mut f: impl FnMut() -> Duration,
11) -> SubBenchResult {
12 profiling::scope!("iter", name);
13
14 let mut iterations = 0_u32;
15 let mut duration = Duration::ZERO;
16
17 let control = if let Some(override_control) = ctx.override_iters {
18 override_control
19 } else {
20 ctx.default_iterations
21 };
22
23 while !control.finished(iterations, duration) {
24 duration += f();
25 iterations += 1;
26 }
27
28 SubBenchResult {
29 name: name.to_string(),
30 avg_duration_per_iteration: duration / iterations,
31 iterations,
32 throughput_unit: throughput_unit.to_string(),
33 throughput_count_per_iteration,
34 }
35}
36
37pub fn iter_auto(
38 ctx: &BenchmarkContext,
39 name: &str,
40 throughput_unit: &str,
41 throughput_count_per_iteration: u32,
42 mut f: impl FnMut(),
43) -> SubBenchResult {
44 iter(
45 ctx,
46 name,
47 throughput_unit,
48 throughput_count_per_iteration,
49 || {
50 let start = std::time::Instant::now();
51 f();
52 start.elapsed()
53 },
54 )
55}
56
57pub fn iter_many(
58 ctx: &BenchmarkContext,
59 names: Vec<String>,
60 throughput_unit: &str,
61 throughput_count_per_iteration: u32,
62 mut f: impl FnMut() -> Vec<Duration>,
63) -> Vec<SubBenchResult> {
64 profiling::scope!("iter", &*names[0]);
65
66 let mut iterations = 0_u32;
67 let mut durations = vec![Duration::ZERO; names.len()];
68
69 let control = if let Some(override_control) = ctx.override_iters {
70 override_control
71 } else {
72 LoopControl::Time(Duration::from_secs(1))
73 };
74
75 while !control.finished(iterations, *durations.first().unwrap_or(&Duration::ZERO)) {
78 let iteration_durations = f();
79 assert_eq!(iteration_durations.len(), names.len());
80 for (i, dur) in iteration_durations.into_iter().enumerate() {
81 durations[i] += dur;
82 }
83 iterations += 1;
84 }
85
86 durations
87 .into_iter()
88 .enumerate()
89 .map(|(i, d)| SubBenchResult {
90 name: names[i].to_string(),
91 avg_duration_per_iteration: d / iterations,
92 iterations,
93 throughput_unit: throughput_unit.to_string(),
94 throughput_count_per_iteration,
95 })
96 .collect()
97}