|
| 1 | +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +//! Benchmarks for `MetricsPool` type erasure and its two-pass write path. |
| 5 | +//! |
| 6 | +//! Run: `cargo bench -p metrique-util --bench metrics_pool --features metrics-pool` |
| 7 | +
|
| 8 | +use std::borrow::Cow; |
| 9 | +use std::time::SystemTime; |
| 10 | + |
| 11 | +use divan::{Bencher, black_box}; |
| 12 | +use metrique::unit_of_work::metrics; |
| 13 | +use metrique::writer::{EntryConfig, EntryWriter, Value}; |
| 14 | +use metrique::{CloseValue, InflectableEntry, PascalCase}; |
| 15 | +use metrique_util::MetricsPool; |
| 16 | + |
| 17 | +#[global_allocator] |
| 18 | +static ALLOC: divan::AllocProfiler = divan::AllocProfiler::system(); |
| 19 | + |
| 20 | +fn main() { |
| 21 | + divan::main(); |
| 22 | +} |
| 23 | + |
| 24 | +const SIZES: &[usize] = &[1, 4, 16]; |
| 25 | +const PREFIXES: &[&str] = &[ |
| 26 | + "child_00", "child_01", "child_02", "child_03", "child_04", "child_05", "child_06", "child_07", |
| 27 | + "child_08", "child_09", "child_10", "child_11", "child_12", "child_13", "child_14", "child_15", |
| 28 | +]; |
| 29 | + |
| 30 | +#[metrics] |
| 31 | +struct ChildMetrics { |
| 32 | + count: u64, |
| 33 | + operation: &'static str, |
| 34 | +} |
| 35 | + |
| 36 | +#[derive(Default)] |
| 37 | +struct CountingWriter { |
| 38 | + values: usize, |
| 39 | +} |
| 40 | + |
| 41 | +impl<'a> EntryWriter<'a> for CountingWriter { |
| 42 | + fn timestamp(&mut self, _timestamp: SystemTime) {} |
| 43 | + |
| 44 | + fn value(&mut self, _name: impl Into<Cow<'a, str>>, _value: &(impl Value + ?Sized)) { |
| 45 | + self.values += 1; |
| 46 | + } |
| 47 | + |
| 48 | + fn config(&mut self, _config: &'a dyn EntryConfig) {} |
| 49 | +} |
| 50 | + |
| 51 | +fn populated_pool(entries: usize, collide: bool) -> MetricsPool { |
| 52 | + let pool = MetricsPool::new(); |
| 53 | + let base = pool.handle(); |
| 54 | + for index in 0..entries { |
| 55 | + let handle = if collide { |
| 56 | + base.clone() |
| 57 | + } else { |
| 58 | + base.with_prefix([PREFIXES[index]]) |
| 59 | + }; |
| 60 | + handle.append(ChildMetrics { |
| 61 | + count: index as u64, |
| 62 | + operation: "PutObject", |
| 63 | + }); |
| 64 | + } |
| 65 | + pool |
| 66 | +} |
| 67 | + |
| 68 | +#[divan::bench(args = SIZES)] |
| 69 | +fn append_unique(bencher: Bencher, entries: usize) { |
| 70 | + bencher |
| 71 | + .counter(entries) |
| 72 | + .with_inputs(|| { |
| 73 | + let pool = MetricsPool::new(); |
| 74 | + let base = pool.handle(); |
| 75 | + let handles = (0..entries) |
| 76 | + .map(|index| base.with_prefix([PREFIXES[index]])) |
| 77 | + .collect::<Vec<_>>(); |
| 78 | + (pool, handles) |
| 79 | + }) |
| 80 | + .bench_values(|(pool, handles)| { |
| 81 | + for (index, handle) in handles.into_iter().enumerate() { |
| 82 | + handle.append(ChildMetrics { |
| 83 | + count: black_box(index as u64), |
| 84 | + operation: black_box("PutObject"), |
| 85 | + }); |
| 86 | + } |
| 87 | + black_box(pool); |
| 88 | + }); |
| 89 | +} |
| 90 | + |
| 91 | +#[divan::bench(args = SIZES)] |
| 92 | +fn close_and_write_unique(bencher: Bencher, entries: usize) { |
| 93 | + bencher |
| 94 | + .counter(entries) |
| 95 | + .with_inputs(|| populated_pool(entries, false)) |
| 96 | + .bench_values(|pool| { |
| 97 | + let closed = pool.close(); |
| 98 | + let mut writer = CountingWriter::default(); |
| 99 | + InflectableEntry::<PascalCase>::write(&closed, &mut writer); |
| 100 | + black_box(writer.values); |
| 101 | + }); |
| 102 | +} |
| 103 | + |
| 104 | +#[divan::bench(args = SIZES)] |
| 105 | +fn close_and_write_collisions(bencher: Bencher, entries: usize) { |
| 106 | + bencher |
| 107 | + .counter(entries) |
| 108 | + .with_inputs(|| populated_pool(entries, true)) |
| 109 | + .bench_values(|pool| { |
| 110 | + let closed = pool.close(); |
| 111 | + let mut writer = CountingWriter::default(); |
| 112 | + InflectableEntry::<PascalCase>::write(&closed, &mut writer); |
| 113 | + black_box(writer.values); |
| 114 | + }); |
| 115 | +} |
| 116 | + |
| 117 | +#[divan::bench(args = SIZES)] |
| 118 | +fn direct_write_baseline(bencher: Bencher, entries: usize) { |
| 119 | + bencher |
| 120 | + .counter(entries) |
| 121 | + .with_inputs(|| { |
| 122 | + (0..entries) |
| 123 | + .map(|index| { |
| 124 | + ChildMetrics { |
| 125 | + count: index as u64, |
| 126 | + operation: "PutObject", |
| 127 | + } |
| 128 | + .close() |
| 129 | + }) |
| 130 | + .collect::<Vec<_>>() |
| 131 | + }) |
| 132 | + .bench_values(|children| { |
| 133 | + let mut writer = CountingWriter::default(); |
| 134 | + for child in &children { |
| 135 | + InflectableEntry::<PascalCase>::write(child, &mut writer); |
| 136 | + } |
| 137 | + black_box(writer.values); |
| 138 | + }); |
| 139 | +} |
0 commit comments