|
| 1 | +//! Example benchmarks demonstrating divan counter usage |
| 2 | +//! |
| 3 | +//! This file shows how to use different types of counters with divan: |
| 4 | +//! - BytesCount: for measuring throughput in bytes |
| 5 | +//! - ItemsCount: for counting processed items |
| 6 | +//! - CharsCount: for counting processed characters |
| 7 | +//! - CyclesCount: for counting processing cycles |
| 8 | +
|
| 9 | +use divan::{counter::*, AllocProfiler, Bencher}; |
| 10 | + |
| 11 | +#[global_allocator] |
| 12 | +static ALLOC: AllocProfiler = AllocProfiler::system(); |
| 13 | + |
| 14 | +fn main() { |
| 15 | + divan::main(); |
| 16 | +} |
| 17 | + |
| 18 | +/// Example data for benchmarks |
| 19 | +const SAMPLE_DATA: &[i32] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; |
| 20 | +const SAMPLE_TEXT: &str = "Hello, world! This is a sample string for benchmarking."; |
| 21 | + |
| 22 | +mod bytes_counter_examples { |
| 23 | + use super::*; |
| 24 | + |
| 25 | + #[divan::bench] |
| 26 | + fn vec_copy_with_bytes_counter(bencher: Bencher) { |
| 27 | + let data = SAMPLE_DATA; |
| 28 | + let bytes = BytesCount::of_slice(data); |
| 29 | + |
| 30 | + bencher |
| 31 | + .counter(bytes) |
| 32 | + .bench(|| -> Vec<i32> { divan::black_box(data).to_vec() }); |
| 33 | + } |
| 34 | + |
| 35 | + #[divan::bench] |
| 36 | + fn string_copy_with_bytes_counter(bencher: Bencher) { |
| 37 | + let text = SAMPLE_TEXT; |
| 38 | + let bytes = BytesCount::of_str(text); |
| 39 | + |
| 40 | + bencher |
| 41 | + .counter(bytes) |
| 42 | + .bench(|| -> String { divan::black_box(text).to_owned() }); |
| 43 | + } |
| 44 | + |
| 45 | + #[divan::bench] |
| 46 | + fn slice_into_vec_with_bytes(bencher: Bencher) { |
| 47 | + let ints = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; |
| 48 | + let bytes = BytesCount::of_slice(ints); |
| 49 | + |
| 50 | + bencher |
| 51 | + .counter(bytes) |
| 52 | + .bench(|| -> Vec<i32> { divan::black_box(ints).into() }); |
| 53 | + } |
| 54 | +} |
| 55 | + |
| 56 | +mod items_counter_examples { |
| 57 | + use super::*; |
| 58 | + |
| 59 | + #[divan::bench] |
| 60 | + fn process_items_with_counter(bencher: Bencher) { |
| 61 | + let data = SAMPLE_DATA; |
| 62 | + let items = ItemsCount::new(data.len()); |
| 63 | + |
| 64 | + bencher |
| 65 | + .counter(items) |
| 66 | + .bench(|| -> Vec<i32> { divan::black_box(data).iter().map(|x| x * 2).collect() }); |
| 67 | + } |
| 68 | + |
| 69 | + #[divan::bench] |
| 70 | + fn filter_items_with_counter(bencher: Bencher) { |
| 71 | + let data = (1..=100).collect::<Vec<_>>(); |
| 72 | + let items = ItemsCount::new(data.len()); |
| 73 | + |
| 74 | + bencher.counter(items).bench(|| -> Vec<i32> { |
| 75 | + divan::black_box(&data) |
| 76 | + .iter() |
| 77 | + .filter(|&&x| x % 2 == 0) |
| 78 | + .copied() |
| 79 | + .collect() |
| 80 | + }); |
| 81 | + } |
| 82 | +} |
| 83 | + |
| 84 | +mod chars_counter_examples { |
| 85 | + use super::*; |
| 86 | + |
| 87 | + #[divan::bench] |
| 88 | + fn count_chars_in_string(bencher: Bencher) { |
| 89 | + let text = SAMPLE_TEXT; |
| 90 | + let chars = CharsCount::of_str(text); |
| 91 | + |
| 92 | + bencher |
| 93 | + .counter(chars) |
| 94 | + .bench(|| -> usize { divan::black_box(text).chars().count() }); |
| 95 | + } |
| 96 | + |
| 97 | + #[divan::bench] |
| 98 | + fn uppercase_chars_with_counter(bencher: Bencher) { |
| 99 | + let text = "hello world with unicode: café naïve résumé"; |
| 100 | + let chars = CharsCount::of_str(text); |
| 101 | + |
| 102 | + bencher |
| 103 | + .counter(chars) |
| 104 | + .bench(|| -> String { divan::black_box(text).to_uppercase() }); |
| 105 | + } |
| 106 | +} |
| 107 | + |
| 108 | +mod cycles_counter_examples { |
| 109 | + use super::*; |
| 110 | + |
| 111 | + #[divan::bench] |
| 112 | + fn simulated_processing_cycles(bencher: Bencher) { |
| 113 | + // Simulate processing 1000 "cycles" of work |
| 114 | + let cycles = CyclesCount::new(1000u32); |
| 115 | + |
| 116 | + bencher.counter(cycles).bench(|| { |
| 117 | + // Simulate some work that processes 1000 cycles |
| 118 | + let mut sum = 0u64; |
| 119 | + for i in 0..1000 { |
| 120 | + sum = sum.wrapping_add(divan::black_box(i)); |
| 121 | + } |
| 122 | + sum |
| 123 | + }); |
| 124 | + } |
| 125 | + |
| 126 | + #[divan::bench] |
| 127 | + fn hash_computation_cycles(bencher: Bencher) { |
| 128 | + let data = SAMPLE_DATA; |
| 129 | + // Treat each hash operation as processing N cycles where N = data length |
| 130 | + let cycles = CyclesCount::new(data.len()); |
| 131 | + |
| 132 | + bencher.counter(cycles).bench(|| -> u64 { |
| 133 | + use std::collections::hash_map::DefaultHasher; |
| 134 | + use std::hash::{Hash, Hasher}; |
| 135 | + |
| 136 | + let mut hasher = DefaultHasher::new(); |
| 137 | + divan::black_box(data).hash(&mut hasher); |
| 138 | + hasher.finish() |
| 139 | + }); |
| 140 | + } |
| 141 | +} |
| 142 | + |
| 143 | +mod multiple_counters_examples { |
| 144 | + use super::*; |
| 145 | + |
| 146 | + #[divan::bench(counters = [BytesCount::of_slice(SAMPLE_DATA), ItemsCount::new(SAMPLE_DATA.len())])] |
| 147 | + fn process_with_multiple_counters() -> Vec<i32> { |
| 148 | + SAMPLE_DATA.iter().map(|x| x * x).collect() |
| 149 | + } |
| 150 | + |
| 151 | + #[divan::bench] |
| 152 | + fn string_processing_multi_counter(bencher: Bencher) { |
| 153 | + let text = "Processing this text with multiple counters"; |
| 154 | + |
| 155 | + bencher |
| 156 | + .counter(BytesCount::of_str(text)) |
| 157 | + .counter(CharsCount::of_str(text)) |
| 158 | + .bench(|| -> Vec<char> { divan::black_box(text).chars().collect() }); |
| 159 | + } |
| 160 | +} |
0 commit comments