|
| 1 | +## Benchmark a closure with `Instant` |
| 2 | + |
| 3 | +[![std-badge]][std] [![cat-time-badge]][cat-time] |
| 4 | + |
| 5 | +Initializes a `weights` vector, calculates half of its total sum into `half_load`, |
| 6 | +and uses `benchmark` to measure the performance of `subset_sum` which takes a slice of weights and a target value and finds a subset whose weights sum to the target. |
| 7 | + |
| 8 | +`benchmark` measures the average time required to call a closure a specified number of times using [`Instant::now`] and [`Instant::elapsed`]. |
| 9 | +It uses [`black_box`] to prevent the compiler from optimizing away the closure's computation since its return value is ignored. |
| 10 | + |
| 11 | +```rust,edition2021 |
| 12 | +use std::time::{Duration, Instant}; |
| 13 | +
|
| 14 | +fn subset_sum(weights: &[u64], target: u64) -> Option<u32> { |
| 15 | + for mask in 0..1u32 << weights.len() { |
| 16 | + let sum: u64 = weights |
| 17 | + .iter() |
| 18 | + .enumerate() |
| 19 | + .filter(|(i, _)| mask >> i & 1 == 1) |
| 20 | + .map(|(_, weight)| weight) |
| 21 | + .sum(); |
| 22 | +
|
| 23 | + if sum == target { |
| 24 | + return Some(mask); |
| 25 | + } |
| 26 | + } |
| 27 | + None |
| 28 | +} |
| 29 | +
|
| 30 | +fn benchmark<F, T>(runs: u32, mut f: F) -> Duration |
| 31 | +where |
| 32 | + F: FnMut() -> T, |
| 33 | +{ |
| 34 | + let start = Instant::now(); |
| 35 | +
|
| 36 | + for _ in 0..runs { |
| 37 | + std::hint::black_box(f()); |
| 38 | + } |
| 39 | +
|
| 40 | + start.elapsed() / runs |
| 41 | +} |
| 42 | +
|
| 43 | +fn main() { |
| 44 | + let weights: Vec<u64> = (1..=18).map(|kg| kg * 2).collect(); |
| 45 | + let half_load = weights.iter().sum::<u64>() / 2; |
| 46 | +
|
| 47 | + for parcels in 12..=weights.len() { |
| 48 | + let mean = benchmark(3, || subset_sum(&weights[..parcels], half_load)); |
| 49 | + println!("{:2} parcels: {:>10.2?}", parcels, mean); |
| 50 | + } |
| 51 | +} |
| 52 | +``` |
| 53 | + |
| 54 | +[`Instant::now`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.now |
| 55 | +[`Instant::elapsed`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.elapsed |
| 56 | +[`black_box`]: https://doc.rust-lang.org/std/hint/fn.black_box.html |
0 commit comments