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
This commit is contained in:
MiniaczQ 2024-10-15 04:38:22 +02:00 committed by GitHub
parent d17de6c105
commit e5e44888c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 129 additions and 1 deletions

View file

@ -5,6 +5,7 @@ mod events;
mod fragmentation;
mod iteration;
mod observers;
mod param;
mod scheduling;
mod world;
@ -16,4 +17,5 @@ criterion_main!(
observers::observer_benches,
scheduling::scheduling_benches,
world::world_benches,
param::param_benches,
);

View file

@ -0,0 +1,31 @@
use bevy_ecs::prelude::*;
use criterion::Criterion;
pub fn combinator_system(criterion: &mut Criterion) {
let mut world = World::new();
let mut group = criterion.benchmark_group("param/combinator_system");
group.warm_up_time(core::time::Duration::from_millis(500));
group.measurement_time(core::time::Duration::from_secs(3));
let mut schedule = Schedule::default();
schedule.add_systems(
(|| {})
.pipe(|| {})
.pipe(|| {})
.pipe(|| {})
.pipe(|| {})
.pipe(|| {})
.pipe(|| {})
.pipe(|| {}),
);
// run once to initialize systems
schedule.run(&mut world);
group.bench_function("8_piped_systems", |bencher| {
bencher.iter(|| {
schedule.run(&mut world);
});
});
group.finish();
}

View file

@ -0,0 +1,49 @@
use bevy_ecs::{
prelude::*,
system::{DynParamBuilder, DynSystemParam, ParamBuilder},
};
use criterion::Criterion;
pub fn dyn_param(criterion: &mut Criterion) {
let mut world = World::new();
let mut group = criterion.benchmark_group("param/combinator_system");
group.warm_up_time(core::time::Duration::from_millis(500));
group.measurement_time(core::time::Duration::from_secs(3));
#[derive(Resource)]
struct R;
let mut schedule = Schedule::default();
let system = (
DynParamBuilder::new::<Res<R>>(ParamBuilder),
DynParamBuilder::new::<Res<R>>(ParamBuilder),
DynParamBuilder::new::<Res<R>>(ParamBuilder),
DynParamBuilder::new::<Res<R>>(ParamBuilder),
DynParamBuilder::new::<Res<R>>(ParamBuilder),
DynParamBuilder::new::<Res<R>>(ParamBuilder),
DynParamBuilder::new::<Res<R>>(ParamBuilder),
DynParamBuilder::new::<Res<R>>(ParamBuilder),
)
.build_state(&mut world)
.build_system(
|_: DynSystemParam,
_: DynSystemParam,
_: DynSystemParam,
_: DynSystemParam,
_: DynSystemParam,
_: DynSystemParam,
_: DynSystemParam,
_: DynSystemParam| {},
);
schedule.add_systems(system);
// run once to initialize systems
schedule.run(&mut world);
group.bench_function("8_dyn_params_system", |bencher| {
bencher.iter(|| {
schedule.run(&mut world);
});
});
group.finish();
}

View file

@ -0,0 +1,11 @@
use criterion::criterion_group;
mod combinator_system;
mod dyn_param;
mod param_set;
use combinator_system::*;
use dyn_param::*;
use param_set::*;
criterion_group!(param_benches, combinator_system, dyn_param, param_set);

View file

@ -0,0 +1,36 @@
use bevy_ecs::prelude::*;
use criterion::Criterion;
pub fn param_set(criterion: &mut Criterion) {
let mut world = World::new();
let mut group = criterion.benchmark_group("param/combinator_system");
group.warm_up_time(core::time::Duration::from_millis(500));
group.measurement_time(core::time::Duration::from_secs(3));
#[derive(Resource)]
struct R;
let mut schedule = Schedule::default();
schedule.add_systems(
|_: ParamSet<(
ResMut<R>,
ResMut<R>,
ResMut<R>,
ResMut<R>,
ResMut<R>,
ResMut<R>,
ResMut<R>,
ResMut<R>,
)>| {},
);
// run once to initialize systems
schedule.run(&mut world);
group.bench_function("8_variant_param_set_system", |bencher| {
bencher.iter(|| {
schedule.run(&mut world);
});
});
group.finish();
}

View file

@ -1,6 +1,5 @@
use bevy_ecs::{
component::Component,
entity::Entity,
system::Commands,
world::{Command, CommandQueue, World},
};