gpui/bench.rs
1/// Defines a Criterion benchmark group for benchmarks annotated with [`gpui::bench`].
2///
3/// This mirrors `criterion::criterion_group!`, but the group measures with the
4/// `gpui::BenchMeasurement` configured by `BENCH_MEASUREMENT` (see
5/// `BenchMeasurement::from_env`). By default Criterion analyzes wall time
6/// while retired instructions, cycles, IPC, context switches, and the other
7/// counters this machine supports are printed per iteration in the GPUI bench
8/// report. `BENCH_MEASUREMENT=instructions` makes Criterion analyze
9/// process-wide instructions instead, `foreground-instructions` the benchmark
10/// thread's alone, and `wall-time` disables all counters. A
11/// `config = ...` expression may set any other Criterion option; its
12/// measurement is replaced. To measure with something else, call
13/// `criterion::criterion_group!` directly with
14/// `config = criterion::Criterion::default().with_measurement(gpui::BenchMeasurement::new(...))`.
15///
16/// [`gpui::bench`]: crate::bench
17#[macro_export]
18macro_rules! bench_group {
19 (name = $name:ident; config = $config:expr; targets = $($target:path),+ $(,)?) => {
20 criterion::criterion_group! {
21 name = $name;
22 config = ($config).with_measurement($crate::BenchMeasurement::from_env_or_exit());
23 targets = $($target),+
24 }
25 };
26 ($name:ident, $($target:path),+ $(,)?) => {
27 $crate::bench_group! {
28 name = $name;
29 config = criterion::Criterion::default();
30 targets = $($target),+
31 }
32 };
33}
34
35/// Defines the entry point for GPUI Criterion benchmark groups.
36///
37/// This mirrors `criterion::criterion_main!` so GPUI benchmark files can keep the
38/// same shape as ordinary Criterion benchmarks. It also installs
39/// [`CountingAllocator`] as the binary's global allocator, so reports include
40/// heap allocations per iteration. It wraps the system allocator by default;
41/// `allocator = Path;` wraps another unit-struct allocator instead, e.g. to
42/// compare allocators, which pay the same small counting cost:
43///
44/// ```ignore
45/// gpui::bench_main!(allocator = mimalloc::MiMalloc; benches);
46/// ```
47///
48/// `allocator = none;` installs no global allocator, leaving Rust's default and
49/// dropping the allocation metrics from reports.
50#[macro_export]
51macro_rules! bench_main {
52 (allocator = none; $($groups:tt)*) => {
53 criterion::criterion_main!($($groups)*);
54 };
55 (allocator = $allocator:path; $($groups:tt)*) => {
56 #[global_allocator]
57 static GPUI_BENCH_ALLOCATOR: $crate::CountingAllocator<$allocator> =
58 $crate::CountingAllocator::new($allocator);
59
60 criterion::criterion_main!($($groups)*);
61 };
62 ($($groups:tt)*) => {
63 $crate::bench_main!(allocator = ::std::alloc::System; $($groups)*);
64 };
65}