fluxbench_core/bencher/
custom.rs1use super::engine::SampleRaw;
4use super::state::Bencher;
5use std::time::Duration;
6
7impl Bencher {
8 #[inline]
15 pub fn iter_custom<F>(&mut self, mut routine: F)
16 where
17 F: FnMut(u64) -> Duration,
18 {
19 if !self.begin_iter() {
20 return;
21 }
22 self.run_loop(|b, n| {
23 b.alloc_reset();
24 let elapsed = routine(n);
25 let (alloc_b, alloc_c) = b.alloc_read();
26 SampleRaw {
27 ns: u64::try_from(elapsed.as_nanos()).unwrap_or(u64::MAX),
28 alloc_b,
29 alloc_c,
30 ..SampleRaw::default()
31 }
32 });
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use crate::bencher::test_support::{fixed, quick};
39 use crate::bencher::{Bencher, run_benchmark_loop};
40 use std::cell::Cell;
41 use std::time::Duration;
42
43 #[test]
44 fn reported_time_becomes_the_sample_mean() {
45 let result = run_benchmark_loop(Bencher::with_config(fixed(4, 25)), |b| {
46 b.iter_custom(|iters| Duration::from_nanos(iters * 100));
47 })
48 .expect("measurement succeeds");
49 assert_eq!(result.samples.len(), 4);
50 assert!(result.samples.iter().all(|s| s.duration_nanos == 100.0));
51 assert!(result.samples.iter().all(|s| s.iterations == 25));
52 assert_eq!(result.iterations, 100);
53 assert_eq!(result.total_time_ns, 100 * 100);
54 }
55
56 #[test]
57 fn every_requested_iteration_is_accounted() {
58 let requested = Cell::new(0_u64);
59 let result = run_benchmark_loop(Bencher::with_config(quick(10)), |b| {
60 b.iter_custom(|iters| {
61 requested.set(requested.get() + iters);
62 Duration::from_nanos(iters * 10)
63 });
64 })
65 .expect("measurement succeeds");
66 assert_eq!(result.samples.len(), 10);
67 assert!(result.warmup_iterations > 0);
68 assert_eq!(
69 requested.get(),
70 result.iterations + result.warmup_iterations
71 );
72 assert_eq!(result.total_time_ns, result.iterations * 10);
73 }
74
75 #[test]
76 fn warmup_sizes_samples_from_the_wall_clock() {
77 let result = run_benchmark_loop(Bencher::with_config(quick(5)), |b| {
79 b.iter_custom(|iters| {
80 std::thread::sleep(Duration::from_millis(iters));
81 Duration::from_nanos(iters)
82 });
83 })
84 .expect("measurement succeeds");
85 assert!(
87 result.iters_per_sample <= 10,
88 "ips: {}",
89 result.iters_per_sample
90 );
91 }
92}