Skip to content

Commit e5e4488

Browse files
authored
Validate param benchmarks (#15885)
# Objective Benchmark overhead of validation for: - `DynSystemParam`, - `ParamSet`, - combinator systems. Needed for #15606 ## Solution As noted in objective, I've added 3 benchmarks, where each uses an excessive amount of the specific functionality. I benchmark on the level of schedules, rather than individual `validate_param` calls, so we get a better idea how changes to the code impact memory-lookup, etc. related side effects. ## Testing ``` param/combinator_system/8_piped_systems time: [1.7560 µs 1.7865 µs 1.8180 µs] change: [+4.5244% +6.7955% +9.1413%] (p = 0.00 < 0.05) Performance has regressed. Found 2 outliers among 100 measurements (2.00%) 1 (1.00%) high mild 1 (1.00%) high severe param/combinator_system/8_dyn_params_system time: [89.354 ns 89.790 ns 90.300 ns] change: [+0.6751% +1.6825% +2.6842%] (p = 0.00 < 0.05) Change within noise threshold. Found 9 outliers among 100 measurements (9.00%) 6 (6.00%) high mild 3 (3.00%) high severe param/combinator_system/8_variant_param_set_system time: [88.295 ns 89.202 ns 90.208 ns] change: [+0.1320% +1.0060% +1.8482%] (p = 0.02 < 0.05) Change within noise threshold. Found 4 outliers among 100 measurements (4.00%) 4 (4.00%) high mild ``` 2 back-to-back runs of the benchmarks, there is quire a lot of noise, can use feedback on fixing that
1 parent d17de6c commit e5e4488

File tree

6 files changed

+129
-1
lines changed

6 files changed

+129
-1
lines changed

benches/benches/bevy_ecs/benches.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod events;
55
mod fragmentation;
66
mod iteration;
77
mod observers;
8+
mod param;
89
mod scheduling;
910
mod world;
1011

@@ -16,4 +17,5 @@ criterion_main!(
1617
observers::observer_benches,
1718
scheduling::scheduling_benches,
1819
world::world_benches,
20+
param::param_benches,
1921
);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use bevy_ecs::prelude::*;
2+
use criterion::Criterion;
3+
4+
pub fn combinator_system(criterion: &mut Criterion) {
5+
let mut world = World::new();
6+
let mut group = criterion.benchmark_group("param/combinator_system");
7+
8+
group.warm_up_time(core::time::Duration::from_millis(500));
9+
group.measurement_time(core::time::Duration::from_secs(3));
10+
11+
let mut schedule = Schedule::default();
12+
schedule.add_systems(
13+
(|| {})
14+
.pipe(|| {})
15+
.pipe(|| {})
16+
.pipe(|| {})
17+
.pipe(|| {})
18+
.pipe(|| {})
19+
.pipe(|| {})
20+
.pipe(|| {}),
21+
);
22+
// run once to initialize systems
23+
schedule.run(&mut world);
24+
group.bench_function("8_piped_systems", |bencher| {
25+
bencher.iter(|| {
26+
schedule.run(&mut world);
27+
});
28+
});
29+
30+
group.finish();
31+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use bevy_ecs::{
2+
prelude::*,
3+
system::{DynParamBuilder, DynSystemParam, ParamBuilder},
4+
};
5+
use criterion::Criterion;
6+
7+
pub fn dyn_param(criterion: &mut Criterion) {
8+
let mut world = World::new();
9+
let mut group = criterion.benchmark_group("param/combinator_system");
10+
11+
group.warm_up_time(core::time::Duration::from_millis(500));
12+
group.measurement_time(core::time::Duration::from_secs(3));
13+
14+
#[derive(Resource)]
15+
struct R;
16+
17+
let mut schedule = Schedule::default();
18+
let system = (
19+
DynParamBuilder::new::<Res<R>>(ParamBuilder),
20+
DynParamBuilder::new::<Res<R>>(ParamBuilder),
21+
DynParamBuilder::new::<Res<R>>(ParamBuilder),
22+
DynParamBuilder::new::<Res<R>>(ParamBuilder),
23+
DynParamBuilder::new::<Res<R>>(ParamBuilder),
24+
DynParamBuilder::new::<Res<R>>(ParamBuilder),
25+
DynParamBuilder::new::<Res<R>>(ParamBuilder),
26+
DynParamBuilder::new::<Res<R>>(ParamBuilder),
27+
)
28+
.build_state(&mut world)
29+
.build_system(
30+
|_: DynSystemParam,
31+
_: DynSystemParam,
32+
_: DynSystemParam,
33+
_: DynSystemParam,
34+
_: DynSystemParam,
35+
_: DynSystemParam,
36+
_: DynSystemParam,
37+
_: DynSystemParam| {},
38+
);
39+
schedule.add_systems(system);
40+
// run once to initialize systems
41+
schedule.run(&mut world);
42+
group.bench_function("8_dyn_params_system", |bencher| {
43+
bencher.iter(|| {
44+
schedule.run(&mut world);
45+
});
46+
});
47+
48+
group.finish();
49+
}

benches/benches/bevy_ecs/param/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use criterion::criterion_group;
2+
3+
mod combinator_system;
4+
mod dyn_param;
5+
mod param_set;
6+
7+
use combinator_system::*;
8+
use dyn_param::*;
9+
use param_set::*;
10+
11+
criterion_group!(param_benches, combinator_system, dyn_param, param_set);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use bevy_ecs::prelude::*;
2+
use criterion::Criterion;
3+
4+
pub fn param_set(criterion: &mut Criterion) {
5+
let mut world = World::new();
6+
let mut group = criterion.benchmark_group("param/combinator_system");
7+
8+
group.warm_up_time(core::time::Duration::from_millis(500));
9+
group.measurement_time(core::time::Duration::from_secs(3));
10+
11+
#[derive(Resource)]
12+
struct R;
13+
14+
let mut schedule = Schedule::default();
15+
schedule.add_systems(
16+
|_: ParamSet<(
17+
ResMut<R>,
18+
ResMut<R>,
19+
ResMut<R>,
20+
ResMut<R>,
21+
ResMut<R>,
22+
ResMut<R>,
23+
ResMut<R>,
24+
ResMut<R>,
25+
)>| {},
26+
);
27+
// run once to initialize systems
28+
schedule.run(&mut world);
29+
group.bench_function("8_variant_param_set_system", |bencher| {
30+
bencher.iter(|| {
31+
schedule.run(&mut world);
32+
});
33+
});
34+
35+
group.finish();
36+
}

benches/benches/bevy_ecs/world/commands.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use bevy_ecs::{
22
component::Component,
3-
entity::Entity,
43
system::Commands,
54
world::{Command, CommandQueue, World},
65
};

0 commit comments

Comments
 (0)