Skip to content

Commit 6f06762

Browse files
BD103ecoskey
authored andcommitted
Make benchmark setup consistent (bevyengine#16733)
# Objective - Benchmarks are inconsistently setup, there are several that do not compile, and several others that need to be reformatted. - Related / precursor to bevyengine#16647, this is part of my attempt migrating [`bevy-bencher`](https://github.com/TheBevyFlock/bevy-bencher) to the official benchmarks. ## Solution > [!TIP] > > I recommend reviewing this PR commit-by-commit, instead of all at once! In 5d26f56 I reorganized how benches were registered. Now this is one `[[bench]]` per Bevy crate. In each crate benchmark folder, there is a `main.rs` that calls `criterion_main!`. I also disabled automatic benchmark discovery, which isn't necessarily required, but may clear up confusion with our custom setup. I also fixed a few errors that were causing the benchmarks to fail to compile. In afc8d33 I ran `rustfmt` on all of the benchmarks. In d6cdf96 I fixed all of the Clippy warnings. In ee94d48 I fixed some of the benchmarks' usage of `black_box()`. I ended up opening rust-lang/rust#133942 due to this, which should help prevent this in the future. In cbe1688 I renamed all of the ECS benchmark groups to be called `benches`, to be consistent with the other crate benchmarks. In e701c21 and 8815bb7 I re-ordered some imports and module definitions, and uplifted `fragmentation/mod.rs` to `fragementation.rs`. Finally, in b0065e0 I organized `Cargo.toml` and bumped Criterion to v0.5. ## Testing - `cd benches && cargo clippy --benches` - `cd benches && cargo fmt --all`
1 parent 24221a3 commit 6f06762

34 files changed

+178
-185
lines changed

benches/Cargo.toml

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ edition = "2021"
44
description = "Benchmarks that test Bevy's performance"
55
publish = false
66
license = "MIT OR Apache-2.0"
7+
# Do not automatically discover benchmarks, we specify them manually instead.
8+
autobenches = false
79

810
[dev-dependencies]
9-
glam = "0.29"
10-
rand = "0.8"
11-
rand_chacha = "0.3"
12-
criterion = { version = "0.3", features = ["html_reports"] }
11+
# Bevy crates
1312
bevy_app = { path = "../crates/bevy_app" }
1413
bevy_ecs = { path = "../crates/bevy_ecs", features = ["multi_threaded"] }
1514
bevy_hierarchy = { path = "../crates/bevy_hierarchy" }
@@ -22,70 +21,47 @@ bevy_render = { path = "../crates/bevy_render" }
2221
bevy_tasks = { path = "../crates/bevy_tasks" }
2322
bevy_utils = { path = "../crates/bevy_utils" }
2423

25-
# make bevy_render compile on linux. x11 vs wayland does not matter here as the benches do not actually use a window
24+
# Other crates
25+
criterion = { version = "0.5.1", features = ["html_reports"] }
26+
glam = "0.29"
27+
rand = "0.8"
28+
rand_chacha = "0.3"
29+
30+
# Make `bevy_render` compile on Linux with x11 windowing. x11 vs. Wayland does not matter here
31+
# because the benches do not actually open any windows.
2632
[target.'cfg(target_os = "linux")'.dev-dependencies]
2733
bevy_winit = { path = "../crates/bevy_winit", features = ["x11"] }
2834

2935
[profile.release]
3036
opt-level = 3
3137
lto = true
3238

33-
[[bench]]
34-
name = "change_detection"
35-
path = "benches/bevy_ecs/change_detection.rs"
36-
harness = false
37-
3839
[[bench]]
3940
name = "ecs"
40-
path = "benches/bevy_ecs/benches.rs"
41-
harness = false
42-
43-
[[bench]]
44-
name = "ray_mesh_intersection"
45-
path = "benches/bevy_picking/ray_mesh_intersection.rs"
46-
harness = false
47-
48-
[[bench]]
49-
name = "reflect_function"
50-
path = "benches/bevy_reflect/function.rs"
51-
harness = false
52-
53-
[[bench]]
54-
name = "reflect_list"
55-
path = "benches/bevy_reflect/list.rs"
56-
harness = false
57-
58-
[[bench]]
59-
name = "reflect_map"
60-
path = "benches/bevy_reflect/map.rs"
61-
harness = false
62-
63-
[[bench]]
64-
name = "reflect_struct"
65-
path = "benches/bevy_reflect/struct.rs"
41+
path = "benches/bevy_ecs/main.rs"
6642
harness = false
6743

6844
[[bench]]
69-
name = "parse_reflect_path"
70-
path = "benches/bevy_reflect/path.rs"
45+
name = "math"
46+
path = "benches/bevy_math/main.rs"
7147
harness = false
7248

7349
[[bench]]
74-
name = "iter"
75-
path = "benches/bevy_tasks/iter.rs"
50+
name = "picking"
51+
path = "benches/bevy_picking/main.rs"
7652
harness = false
7753

7854
[[bench]]
79-
name = "bezier"
80-
path = "benches/bevy_math/bezier.rs"
55+
name = "reflect"
56+
path = "benches/bevy_reflect/main.rs"
8157
harness = false
8258

8359
[[bench]]
84-
name = "torus"
85-
path = "benches/bevy_render/torus.rs"
60+
name = "render"
61+
path = "benches/bevy_render/main.rs"
8662
harness = false
8763

8864
[[bench]]
89-
name = "entity_hash"
90-
path = "benches/bevy_ecs/world/entity_hash.rs"
65+
name = "tasks"
66+
path = "benches/bevy_tasks/main.rs"
9167
harness = false

benches/benches/bevy_ecs/benches.rs

Lines changed: 0 additions & 23 deletions
This file was deleted.

benches/benches/bevy_ecs/change_detection.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bevy_ecs::{
55
query::QueryFilter,
66
world::World,
77
};
8-
use criterion::{black_box, criterion_group, criterion_main, Criterion};
8+
use criterion::{black_box, criterion_group, Criterion};
99
use rand::{prelude::SliceRandom, SeedableRng};
1010
use rand_chacha::ChaCha8Rng;
1111

@@ -17,7 +17,6 @@ criterion_group!(
1717
none_changed_detection,
1818
multiple_archetype_none_changed_detection
1919
);
20-
criterion_main!(benches);
2120

2221
macro_rules! modify {
2322
($components:ident;$($index:tt),*) => {
@@ -96,7 +95,7 @@ fn all_added_detection_generic<T: Component + Default>(group: &mut BenchGroup, e
9695
},
9796
|(ref mut world, ref mut query)| {
9897
let mut count = 0;
99-
for entity in query.iter(&world) {
98+
for entity in query.iter(world) {
10099
black_box(entity);
101100
count += 1;
102101
}
@@ -144,7 +143,7 @@ fn all_changed_detection_generic<T: Component<Mutability = Mutable> + Default +
144143
},
145144
|(ref mut world, ref mut query)| {
146145
let mut count = 0;
147-
for entity in query.iter(&world) {
146+
for entity in query.iter(world) {
148147
black_box(entity);
149148
count += 1;
150149
}
@@ -196,7 +195,7 @@ fn few_changed_detection_generic<T: Component<Mutability = Mutable> + Default +
196195
(world, query)
197196
},
198197
|(ref mut world, ref mut query)| {
199-
for entity in query.iter(&world) {
198+
for entity in query.iter(world) {
200199
black_box(entity);
201200
}
202201
},
@@ -238,7 +237,7 @@ fn none_changed_detection_generic<T: Component<Mutability = Mutable> + Default>(
238237
},
239238
|(ref mut world, ref mut query)| {
240239
let mut count = 0;
241-
for entity in query.iter(&world) {
240+
for entity in query.iter(world) {
242241
black_box(entity);
243242
count += 1;
244243
}
@@ -298,7 +297,9 @@ fn add_archetypes_entities<T: Component<Mutability = Mutable> + Default>(
298297
}
299298
}
300299
}
301-
fn multiple_archetype_none_changed_detection_generic<T: Component<Mutability = Mutable> + Default + BenchModify>(
300+
fn multiple_archetype_none_changed_detection_generic<
301+
T: Component<Mutability = Mutable> + Default + BenchModify,
302+
>(
302303
group: &mut BenchGroup,
303304
archetype_count: u16,
304305
entity_count: u32,
@@ -342,7 +343,7 @@ fn multiple_archetype_none_changed_detection_generic<T: Component<Mutability = M
342343
},
343344
|(ref mut world, ref mut query)| {
344345
let mut count = 0;
345-
for entity in query.iter(&world) {
346+
for entity in query.iter(world) {
346347
black_box(entity);
347348
count += 1;
348349
}

benches/benches/bevy_ecs/components/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
use criterion::*;
2-
1+
mod add_remove;
32
mod add_remove_big_sparse_set;
43
mod add_remove_big_table;
54
mod add_remove_sparse_set;
65
mod add_remove_table;
76
mod add_remove_very_big_table;
8-
mod add_remove;
97
mod archetype_updates;
108
mod insert_simple;
119
mod insert_simple_unbatched;
1210

1311
use archetype_updates::*;
12+
use criterion::{criterion_group, Criterion};
1413

1514
criterion_group!(
16-
components_benches,
15+
benches,
1716
add_remove,
1817
add_remove_big,
1918
add_remove_very_big,

benches/benches/bevy_ecs/empty_archetypes.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use bevy_ecs::{component::Component, prelude::*, world::World};
2-
use bevy_tasks::{ComputeTaskPool, TaskPool};
3-
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
1+
use bevy_ecs::{component::Component, prelude::*, schedule::ExecutorKind, world::World};
2+
use criterion::{black_box, criterion_group, BenchmarkId, Criterion};
43

54
criterion_group!(benches, empty_archetypes);
6-
criterion_main!(benches);
75

86
#[derive(Component)]
97
struct A<const N: u16>(f32);
@@ -47,13 +45,12 @@ fn for_each(
4745
&A<12>,
4846
)>,
4947
) {
50-
query.for_each(|comp| {
48+
query.iter().for_each(|comp| {
5149
black_box(comp);
5250
});
5351
}
5452

5553
fn par_for_each(
56-
task_pool: Res<ComputeTaskPool>,
5754
query: Query<(
5855
&A<0>,
5956
&A<1>,
@@ -70,25 +67,29 @@ fn par_for_each(
7067
&A<12>,
7168
)>,
7269
) {
73-
query.par_for_each(&*task_pool, 64, |comp| {
70+
query.par_iter().for_each(|comp| {
7471
black_box(comp);
7572
});
7673
}
7774

7875
fn setup(parallel: bool, setup: impl FnOnce(&mut Schedule)) -> (World, Schedule) {
79-
let mut world = World::new();
76+
let world = World::new();
8077
let mut schedule = Schedule::default();
81-
if parallel {
82-
world.insert_resource(ComputeTaskPool(TaskPool::default()));
83-
}
78+
79+
schedule.set_executor_kind(match parallel {
80+
true => ExecutorKind::MultiThreaded,
81+
false => ExecutorKind::SingleThreaded,
82+
});
83+
8484
setup(&mut schedule);
85+
8586
(world, schedule)
8687
}
8788

8889
/// create `count` entities with distinct archetypes
8990
fn add_archetypes(world: &mut World, count: u16) {
9091
for i in 0..count {
91-
let mut e = world.spawn();
92+
let mut e = world.spawn_empty();
9293
e.insert(A::<0>(1.0));
9394
e.insert(A::<1>(1.0));
9495
e.insert(A::<2>(1.0));
@@ -158,7 +159,7 @@ fn empty_archetypes(criterion: &mut Criterion) {
158159
});
159160
add_archetypes(&mut world, archetype_count);
160161
world.clear_entities();
161-
let mut e = world.spawn();
162+
let mut e = world.spawn_empty();
162163
e.insert(A::<0>(1.0));
163164
e.insert(A::<1>(1.0));
164165
e.insert(A::<2>(1.0));
@@ -189,7 +190,7 @@ fn empty_archetypes(criterion: &mut Criterion) {
189190
});
190191
add_archetypes(&mut world, archetype_count);
191192
world.clear_entities();
192-
let mut e = world.spawn();
193+
let mut e = world.spawn_empty();
193194
e.insert(A::<0>(1.0));
194195
e.insert(A::<1>(1.0));
195196
e.insert(A::<2>(1.0));
@@ -220,7 +221,7 @@ fn empty_archetypes(criterion: &mut Criterion) {
220221
});
221222
add_archetypes(&mut world, archetype_count);
222223
world.clear_entities();
223-
let mut e = world.spawn();
224+
let mut e = world.spawn_empty();
224225
e.insert(A::<0>(1.0));
225226
e.insert(A::<1>(1.0));
226227
e.insert(A::<2>(1.0));

benches/benches/bevy_ecs/events/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use criterion::*;
2-
31
mod iter;
42
mod send;
53

6-
criterion_group!(event_benches, send, iter);
4+
use criterion::{criterion_group, Criterion};
5+
6+
criterion_group!(benches, send, iter);
77

88
fn send(c: &mut Criterion) {
99
let mut group = c.benchmark_group("events_send");

benches/benches/bevy_ecs/fragmentation/mod.rs renamed to benches/benches/bevy_ecs/fragmentation.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use bevy_ecs::prelude::*;
22
use bevy_ecs::system::SystemState;
3+
use core::hint::black_box;
34
use criterion::*;
45
use glam::*;
5-
use core::hint::black_box;
66

7-
criterion_group!(fragmentation_benches, iter_frag_empty);
7+
criterion_group!(benches, iter_frag_empty);
88

99
#[derive(Component, Default)]
1010
struct Table<const X: usize = 0>(usize);

benches/benches/bevy_ecs/iteration/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use criterion::*;
2-
31
mod heavy_compute;
42
mod iter_frag;
53
mod iter_frag_foreach;
@@ -22,10 +20,11 @@ mod iter_simple_wide_sparse_set;
2220
mod par_iter_simple;
2321
mod par_iter_simple_foreach_hybrid;
2422

23+
use criterion::{criterion_group, Criterion};
2524
use heavy_compute::*;
2625

2726
criterion_group!(
28-
iterations_benches,
27+
benches,
2928
iter_frag,
3029
iter_frag_sparse,
3130
iter_simple,
@@ -136,7 +135,7 @@ fn par_iter_simple(c: &mut Criterion) {
136135
b.iter(move || bench.run());
137136
});
138137
}
139-
group.bench_function(format!("hybrid"), |b| {
138+
group.bench_function("hybrid".to_string(), |b| {
140139
let mut bench = par_iter_simple_foreach_hybrid::Benchmark::new();
141140
b.iter(move || bench.run());
142141
});

0 commit comments

Comments
 (0)