Skip to content

Commit c03e494

Browse files
authored
Migrate reflection benchmarks to new naming system (#16986)
# Objective - Please see #16647 for the full reasoning behind this change. ## Solution - Create the `bench!` macro, which generates the name of the benchmark at compile time. Migrating is a single line change, and it will automatically update if you move the benchmark to a different module: ```diff + use benches::bench; fn my_benchmark(c: &mut Criterion) { - c.bench_function("my_benchmark", |b| {}); + c.bench_function(bench!("my_benchmark"), |b| {}); } ``` - Migrate all reflection benchmarks to use `bench!`. - Fix a few places where `black_box()` or Criterion is misused. ## Testing ```sh cd benches # Will take a long time! cargo bench --bench reflect # List out the names of all reflection benchmarks, to ensure I didn't miss anything. cargo bench --bench reflect -- --list # Check for linter warnings. cargo clippy --bench reflect # Run each benchmark once. cargo test --bench reflect ```
1 parent 3eae859 commit c03e494

File tree

7 files changed

+262
-165
lines changed

7 files changed

+262
-165
lines changed

benches/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ license = "MIT OR Apache-2.0"
77
# Do not automatically discover benchmarks, we specify them manually instead.
88
autobenches = false
99

10+
[dependencies]
11+
# The primary crate that runs and analyzes our benchmarks. This is a regular dependency because the
12+
# `bench!` macro refers to it in its documentation.
13+
criterion = { version = "0.5.1", features = ["html_reports"] }
14+
1015
[dev-dependencies]
1116
# Bevy crates
1217
bevy_app = { path = "../crates/bevy_app" }
@@ -22,7 +27,6 @@ bevy_tasks = { path = "../crates/bevy_tasks" }
2227
bevy_utils = { path = "../crates/bevy_utils" }
2328

2429
# Other crates
25-
criterion = { version = "0.5.1", features = ["html_reports"] }
2630
glam = "0.29"
2731
rand = "0.8"
2832
rand_chacha = "0.3"

benches/benches/bevy_reflect/function.rs

Lines changed: 110 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
1+
use core::hint::black_box;
2+
3+
use benches::bench;
14
use bevy_reflect::func::{ArgList, IntoFunction, IntoFunctionMut, TypedFunction};
2-
use criterion::{criterion_group, BatchSize, Criterion};
5+
use criterion::{criterion_group, BatchSize, BenchmarkId, Criterion};
36

4-
criterion_group!(benches, typed, into, call, overload, clone);
7+
criterion_group!(
8+
benches,
9+
typed,
10+
into,
11+
call,
12+
clone,
13+
with_overload,
14+
call_overload,
15+
);
516

617
fn add(a: i32, b: i32) -> i32 {
718
a + b
819
}
920

1021
fn typed(c: &mut Criterion) {
11-
c.benchmark_group("typed")
22+
c.benchmark_group(bench!("typed"))
1223
.bench_function("function", |b| {
1324
b.iter(|| add.get_function_info());
1425
})
@@ -25,7 +36,7 @@ fn typed(c: &mut Criterion) {
2536
}
2637

2738
fn into(c: &mut Criterion) {
28-
c.benchmark_group("into")
39+
c.benchmark_group(bench!("into"))
2940
.bench_function("function", |b| {
3041
b.iter(|| add.into_function());
3142
})
@@ -36,17 +47,18 @@ fn into(c: &mut Criterion) {
3647
})
3748
.bench_function("closure_mut", |b| {
3849
let mut _capture = 25;
50+
// `move` is required here because `into_function_mut()` takes ownership of `self`.
3951
let closure = move |a: i32| _capture += a;
4052
b.iter(|| closure.into_function_mut());
4153
});
4254
}
4355

4456
fn call(c: &mut Criterion) {
45-
c.benchmark_group("call")
57+
c.benchmark_group(bench!("call"))
4658
.bench_function("trait_object", |b| {
4759
b.iter_batched(
4860
|| Box::new(add) as Box<dyn Fn(i32, i32) -> i32>,
49-
|func| func(75, 25),
61+
|func| func(black_box(75), black_box(25)),
5062
BatchSize::SmallInput,
5163
);
5264
})
@@ -78,35 +90,43 @@ fn call(c: &mut Criterion) {
7890
});
7991
}
8092

81-
fn overload(c: &mut Criterion) {
82-
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
83-
a + b
84-
}
93+
fn clone(c: &mut Criterion) {
94+
c.benchmark_group(bench!("clone"))
95+
.bench_function("function", |b| {
96+
let add = add.into_function();
97+
b.iter(|| add.clone());
98+
});
99+
}
100+
101+
fn simple<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
102+
a + b
103+
}
85104

86-
#[expect(clippy::too_many_arguments)]
87-
fn complex<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(
88-
_: T0,
89-
_: T1,
90-
_: T2,
91-
_: T3,
92-
_: T4,
93-
_: T5,
94-
_: T6,
95-
_: T7,
96-
_: T8,
97-
_: T9,
98-
) {
99-
}
105+
#[expect(clippy::too_many_arguments)]
106+
fn complex<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(
107+
_: T0,
108+
_: T1,
109+
_: T2,
110+
_: T3,
111+
_: T4,
112+
_: T5,
113+
_: T6,
114+
_: T7,
115+
_: T8,
116+
_: T9,
117+
) {
118+
}
100119

101-
c.benchmark_group("with_overload")
102-
.bench_function("01_simple_overload", |b| {
120+
fn with_overload(c: &mut Criterion) {
121+
c.benchmark_group(bench!("with_overload"))
122+
.bench_function(BenchmarkId::new("simple_overload", 1), |b| {
103123
b.iter_batched(
104-
|| add::<i8>.into_function(),
105-
|func| func.with_overload(add::<i16>),
124+
|| simple::<i8>.into_function(),
125+
|func| func.with_overload(simple::<i16>),
106126
BatchSize::SmallInput,
107127
);
108128
})
109-
.bench_function("01_complex_overload", |b| {
129+
.bench_function(BenchmarkId::new("complex_overload", 1), |b| {
110130
b.iter_batched(
111131
|| complex::<i8, i16, i32, i64, i128, u8, u16, u32, u64, u128>.into_function(),
112132
|func| {
@@ -115,18 +135,18 @@ fn overload(c: &mut Criterion) {
115135
BatchSize::SmallInput,
116136
);
117137
})
118-
.bench_function("03_simple_overload", |b| {
138+
.bench_function(BenchmarkId::new("simple_overload", 3), |b| {
119139
b.iter_batched(
120-
|| add::<i8>.into_function(),
140+
|| simple::<i8>.into_function(),
121141
|func| {
122-
func.with_overload(add::<i16>)
123-
.with_overload(add::<i32>)
124-
.with_overload(add::<i64>)
142+
func.with_overload(simple::<i16>)
143+
.with_overload(simple::<i32>)
144+
.with_overload(simple::<i64>)
125145
},
126146
BatchSize::SmallInput,
127147
);
128148
})
129-
.bench_function("03_complex_overload", |b| {
149+
.bench_function(BenchmarkId::new("complex_overload", 3), |b| {
130150
b.iter_batched(
131151
|| complex::<i8, i16, i32, i64, i128, u8, u16, u32, u64, u128>.into_function(),
132152
|func| {
@@ -137,24 +157,24 @@ fn overload(c: &mut Criterion) {
137157
BatchSize::SmallInput,
138158
);
139159
})
140-
.bench_function("10_simple_overload", |b| {
160+
.bench_function(BenchmarkId::new("simple_overload", 10), |b| {
141161
b.iter_batched(
142-
|| add::<i8>.into_function(),
162+
|| simple::<i8>.into_function(),
143163
|func| {
144-
func.with_overload(add::<i16>)
145-
.with_overload(add::<i32>)
146-
.with_overload(add::<i64>)
147-
.with_overload(add::<i128>)
148-
.with_overload(add::<u8>)
149-
.with_overload(add::<u16>)
150-
.with_overload(add::<u32>)
151-
.with_overload(add::<u64>)
152-
.with_overload(add::<u128>)
164+
func.with_overload(simple::<i16>)
165+
.with_overload(simple::<i32>)
166+
.with_overload(simple::<i64>)
167+
.with_overload(simple::<i128>)
168+
.with_overload(simple::<u8>)
169+
.with_overload(simple::<u16>)
170+
.with_overload(simple::<u32>)
171+
.with_overload(simple::<u64>)
172+
.with_overload(simple::<u128>)
153173
},
154174
BatchSize::SmallInput,
155175
);
156176
})
157-
.bench_function("10_complex_overload", |b| {
177+
.bench_function(BenchmarkId::new("complex_overload", 10), |b| {
158178
b.iter_batched(
159179
|| complex::<i8, i16, i32, i64, i128, u8, u16, u32, u64, u128>.into_function(),
160180
|func| {
@@ -171,41 +191,41 @@ fn overload(c: &mut Criterion) {
171191
BatchSize::SmallInput,
172192
);
173193
})
174-
.bench_function("01_nested_simple_overload", |b| {
194+
.bench_function(BenchmarkId::new("nested_simple_overload", 1), |b| {
175195
b.iter_batched(
176-
|| add::<i8>.into_function(),
177-
|func| func.with_overload(add::<i16>),
196+
|| simple::<i8>.into_function(),
197+
|func| func.with_overload(simple::<i16>),
178198
BatchSize::SmallInput,
179199
);
180200
})
181-
.bench_function("03_nested_simple_overload", |b| {
201+
.bench_function(BenchmarkId::new("nested_simple_overload", 3), |b| {
182202
b.iter_batched(
183-
|| add::<i8>.into_function(),
203+
|| simple::<i8>.into_function(),
184204
|func| {
185205
func.with_overload(
186-
add::<i16>
187-
.into_function()
188-
.with_overload(add::<i32>.into_function().with_overload(add::<i64>)),
206+
simple::<i16>.into_function().with_overload(
207+
simple::<i32>.into_function().with_overload(simple::<i64>),
208+
),
189209
)
190210
},
191211
BatchSize::SmallInput,
192212
);
193213
})
194-
.bench_function("10_nested_simple_overload", |b| {
214+
.bench_function(BenchmarkId::new("nested_simple_overload", 10), |b| {
195215
b.iter_batched(
196-
|| add::<i8>.into_function(),
216+
|| simple::<i8>.into_function(),
197217
|func| {
198218
func.with_overload(
199-
add::<i16>.into_function().with_overload(
200-
add::<i32>.into_function().with_overload(
201-
add::<i64>.into_function().with_overload(
202-
add::<i128>.into_function().with_overload(
203-
add::<u8>.into_function().with_overload(
204-
add::<u16>.into_function().with_overload(
205-
add::<u32>.into_function().with_overload(
206-
add::<u64>
219+
simple::<i16>.into_function().with_overload(
220+
simple::<i32>.into_function().with_overload(
221+
simple::<i64>.into_function().with_overload(
222+
simple::<i128>.into_function().with_overload(
223+
simple::<u8>.into_function().with_overload(
224+
simple::<u16>.into_function().with_overload(
225+
simple::<u32>.into_function().with_overload(
226+
simple::<u64>
207227
.into_function()
208-
.with_overload(add::<u128>),
228+
.with_overload(simple::<u128>),
209229
),
210230
),
211231
),
@@ -218,21 +238,23 @@ fn overload(c: &mut Criterion) {
218238
BatchSize::SmallInput,
219239
);
220240
});
241+
}
221242

222-
c.benchmark_group("call_overload")
223-
.bench_function("01_simple_overload", |b| {
243+
fn call_overload(c: &mut Criterion) {
244+
c.benchmark_group(bench!("call_overload"))
245+
.bench_function(BenchmarkId::new("simple_overload", 1), |b| {
224246
b.iter_batched(
225247
|| {
226248
(
227-
add::<i8>.into_function().with_overload(add::<i16>),
249+
simple::<i8>.into_function().with_overload(simple::<i16>),
228250
ArgList::new().push_owned(75_i8).push_owned(25_i8),
229251
)
230252
},
231253
|(func, args)| func.call(args),
232254
BatchSize::SmallInput,
233255
);
234256
})
235-
.bench_function("01_complex_overload", |b| {
257+
.bench_function(BenchmarkId::new("complex_overload", 1), |b| {
236258
b.iter_batched(
237259
|| {
238260
(
@@ -258,23 +280,23 @@ fn overload(c: &mut Criterion) {
258280
BatchSize::SmallInput,
259281
);
260282
})
261-
.bench_function("03_simple_overload", |b| {
283+
.bench_function(BenchmarkId::new("simple_overload", 3), |b| {
262284
b.iter_batched(
263285
|| {
264286
(
265-
add::<i8>
287+
simple::<i8>
266288
.into_function()
267-
.with_overload(add::<i16>)
268-
.with_overload(add::<i32>)
269-
.with_overload(add::<i64>),
289+
.with_overload(simple::<i16>)
290+
.with_overload(simple::<i32>)
291+
.with_overload(simple::<i64>),
270292
ArgList::new().push_owned(75_i32).push_owned(25_i32),
271293
)
272294
},
273295
|(func, args)| func.call(args),
274296
BatchSize::SmallInput,
275297
);
276298
})
277-
.bench_function("03_complex_overload", |b| {
299+
.bench_function(BenchmarkId::new("complex_overload", 3), |b| {
278300
b.iter_batched(
279301
|| {
280302
(
@@ -306,29 +328,29 @@ fn overload(c: &mut Criterion) {
306328
BatchSize::SmallInput,
307329
);
308330
})
309-
.bench_function("10_simple_overload", |b| {
331+
.bench_function(BenchmarkId::new("simple_overload", 10), |b| {
310332
b.iter_batched(
311333
|| {
312334
(
313-
add::<i8>
335+
simple::<i8>
314336
.into_function()
315-
.with_overload(add::<i16>)
316-
.with_overload(add::<i32>)
317-
.with_overload(add::<i64>)
318-
.with_overload(add::<i128>)
319-
.with_overload(add::<u8>)
320-
.with_overload(add::<u16>)
321-
.with_overload(add::<u32>)
322-
.with_overload(add::<u64>)
323-
.with_overload(add::<u128>),
337+
.with_overload(simple::<i16>)
338+
.with_overload(simple::<i32>)
339+
.with_overload(simple::<i64>)
340+
.with_overload(simple::<i128>)
341+
.with_overload(simple::<u8>)
342+
.with_overload(simple::<u16>)
343+
.with_overload(simple::<u32>)
344+
.with_overload(simple::<u64>)
345+
.with_overload(simple::<u128>),
324346
ArgList::new().push_owned(75_u8).push_owned(25_u8),
325347
)
326348
},
327349
|(func, args)| func.call(args),
328350
BatchSize::SmallInput,
329351
);
330352
})
331-
.bench_function("10_complex_overload", |b| {
353+
.bench_function(BenchmarkId::new("complex_overload", 10), |b| {
332354
b.iter_batched(
333355
|| {
334356
(
@@ -379,10 +401,3 @@ fn overload(c: &mut Criterion) {
379401
);
380402
});
381403
}
382-
383-
fn clone(c: &mut Criterion) {
384-
c.benchmark_group("clone").bench_function("function", |b| {
385-
let add = add.into_function();
386-
b.iter(|| add.clone());
387-
});
388-
}

0 commit comments

Comments
 (0)