diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 16b56eca8cf09..165fbce1cb25e 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -18,38 +18,8 @@ bevy_tasks = { path = "../crates/bevy_tasks" } bevy_utils = { path = "../crates/bevy_utils" } [[bench]] -name = "archetype_updates" -path = "benches/bevy_ecs/archetype_updates.rs" -harness = false - -[[bench]] -name = "ecs_bench_suite" -path = "benches/bevy_ecs/ecs_bench_suite/mod.rs" -harness = false - -[[bench]] -name = "run_criteria" -path = "benches/bevy_ecs/run_criteria.rs" -harness = false - -[[bench]] -name = "commands" -path = "benches/bevy_ecs/commands.rs" -harness = false - -[[bench]] -name = "system_stage" -path = "benches/bevy_ecs/stages.rs" -harness = false - -[[bench]] -name = "world_get" -path = "benches/bevy_ecs/world_get.rs" -harness = false - -[[bench]] -name = "schedule" -path = "benches/bevy_ecs/schedule.rs" +name = "ecs" +path = "benches/bevy_ecs/benches.rs" harness = false [[bench]] diff --git a/benches/benches/bevy_ecs/benches.rs b/benches/benches/bevy_ecs/benches.rs new file mode 100644 index 0000000000000..4e0c165655bb3 --- /dev/null +++ b/benches/benches/bevy_ecs/benches.rs @@ -0,0 +1,13 @@ +use criterion::criterion_main; + +mod components; +mod iteration; +mod scheduling; +mod world; + +criterion_main!( + iteration::iterations_benches, + components::components_benches, + scheduling::scheduling_benches, + world::world_benches, +); diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/add_remove.rs b/benches/benches/bevy_ecs/components/add_remove.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/add_remove.rs rename to benches/benches/bevy_ecs/components/add_remove.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/add_remove_big_sparse_set.rs b/benches/benches/bevy_ecs/components/add_remove_big_sparse_set.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/add_remove_big_sparse_set.rs rename to benches/benches/bevy_ecs/components/add_remove_big_sparse_set.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/add_remove_big_table.rs b/benches/benches/bevy_ecs/components/add_remove_big_table.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/add_remove_big_table.rs rename to benches/benches/bevy_ecs/components/add_remove_big_table.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/add_remove_sparse_set.rs b/benches/benches/bevy_ecs/components/add_remove_sparse_set.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/add_remove_sparse_set.rs rename to benches/benches/bevy_ecs/components/add_remove_sparse_set.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/add_remove_table.rs b/benches/benches/bevy_ecs/components/add_remove_table.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/add_remove_table.rs rename to benches/benches/bevy_ecs/components/add_remove_table.rs diff --git a/benches/benches/bevy_ecs/archetype_updates.rs b/benches/benches/bevy_ecs/components/archetype_updates.rs similarity index 92% rename from benches/benches/bevy_ecs/archetype_updates.rs rename to benches/benches/bevy_ecs/components/archetype_updates.rs index dabe7fe0e7a54..26adacd816a6e 100644 --- a/benches/benches/bevy_ecs/archetype_updates.rs +++ b/benches/benches/bevy_ecs/components/archetype_updates.rs @@ -3,10 +3,7 @@ use bevy_ecs::{ schedule::{Stage, SystemStage}, world::World, }; -use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; - -criterion_group!(benches, no_archetypes, added_archetypes); -criterion_main!(benches); +use criterion::{BenchmarkId, Criterion}; #[derive(Component)] struct A(f32); @@ -77,7 +74,7 @@ fn add_archetypes(world: &mut World, count: u16) { } } -fn no_archetypes(criterion: &mut Criterion) { +pub fn no_archetypes(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("no_archetypes"); for i in 0..=5 { let system_count = i * 20; @@ -94,7 +91,7 @@ fn no_archetypes(criterion: &mut Criterion) { } } -fn added_archetypes(criterion: &mut Criterion) { +pub fn added_archetypes(criterion: &mut Criterion) { const SYSTEM_COUNT: usize = 100; let mut group = criterion.benchmark_group("added_archetypes"); for archetype_count in [100, 200, 500, 1000, 2000, 5000, 10000] { diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_insert.rs b/benches/benches/bevy_ecs/components/insert_simple.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_insert.rs rename to benches/benches/bevy_ecs/components/insert_simple.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_insert_unbatched.rs b/benches/benches/bevy_ecs/components/insert_simple_unbatched.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_insert_unbatched.rs rename to benches/benches/bevy_ecs/components/insert_simple_unbatched.rs diff --git a/benches/benches/bevy_ecs/components/mod.rs b/benches/benches/bevy_ecs/components/mod.rs new file mode 100644 index 0000000000000..419f938c91b23 --- /dev/null +++ b/benches/benches/bevy_ecs/components/mod.rs @@ -0,0 +1,65 @@ +use criterion::*; + +mod add_remove_big_sparse_set; +mod add_remove_big_table; +mod add_remove_sparse_set; +mod add_remove_table; +mod archetype_updates; +mod insert_simple; +mod insert_simple_unbatched; + +use archetype_updates::*; + +criterion_group!( + components_benches, + add_remove, + add_remove_big, + insert_simple, + no_archetypes, + added_archetypes, +); + +fn add_remove(c: &mut Criterion) { + let mut group = c.benchmark_group("add_remove"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + group.bench_function("table", |b| { + let mut bench = add_remove_table::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("sparse_set", |b| { + let mut bench = add_remove_sparse_set::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.finish(); +} + +fn add_remove_big(c: &mut Criterion) { + let mut group = c.benchmark_group("add_remove_big"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + group.bench_function("table", |b| { + let mut bench = add_remove_big_table::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("sparse_set", |b| { + let mut bench = add_remove_big_sparse_set::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.finish(); +} + +fn insert_simple(c: &mut Criterion) { + let mut group = c.benchmark_group("insert_simple"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + group.bench_function("base", |b| { + let mut bench = insert_simple::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("unbatched", |b| { + let mut bench = insert_simple_unbatched::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.finish(); +} diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/get_component.rs b/benches/benches/bevy_ecs/ecs_bench_suite/get_component.rs deleted file mode 100644 index 42e20a10923df..0000000000000 --- a/benches/benches/bevy_ecs/ecs_bench_suite/get_component.rs +++ /dev/null @@ -1,23 +0,0 @@ -use bevy_ecs::prelude::*; - -#[derive(Component)] -struct A(f32); - -pub struct Benchmark<'w>(World, Entity, QueryState<&'w mut A>); - -impl<'w> Benchmark<'w> { - pub fn new() -> Self { - let mut world = World::new(); - - let entity = world.spawn().insert(A(0.0)).id(); - let query = world.query::<&mut A>(); - Self(world, entity, query) - } - - pub fn run(&mut self) { - for _x in 0..100000 { - let mut a = unsafe { self.2.get_unchecked(&mut self.0, self.1).unwrap() }; - a.0 += 1.0; - } - } -} diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/get_component_system.rs b/benches/benches/bevy_ecs/ecs_bench_suite/get_component_system.rs deleted file mode 100644 index c746a223304d4..0000000000000 --- a/benches/benches/bevy_ecs/ecs_bench_suite/get_component_system.rs +++ /dev/null @@ -1,29 +0,0 @@ -use bevy_ecs::prelude::*; - -#[derive(Component)] -struct A(f32); - -pub struct Benchmark(World, Entity, Box>); - -impl Benchmark { - pub fn new() -> Self { - let mut world = World::new(); - - let entity = world.spawn().insert(A(0.0)).id(); - fn query_system(In(entity): In, mut query: Query<&mut A>) { - for _ in 0..100_000 { - let mut a = query.get_mut(entity).unwrap(); - a.0 += 1.0; - } - } - - let mut system = IntoSystem::into_system(query_system); - system.initialize(&mut world); - system.update_archetype_component_access(&world); - Self(world, entity, Box::new(system)) - } - - pub fn run(&mut self) { - self.2.run(self.1, &mut self.0); - } -} diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/mod.rs b/benches/benches/bevy_ecs/ecs_bench_suite/mod.rs deleted file mode 100644 index bad7c86e5b44f..0000000000000 --- a/benches/benches/bevy_ecs/ecs_bench_suite/mod.rs +++ /dev/null @@ -1,214 +0,0 @@ -use criterion::*; - -mod add_remove_big_sparse_set; -mod add_remove_big_table; -mod add_remove_sparse_set; -mod add_remove_table; -mod frag_iter; -mod frag_iter_wide; -mod frag_iter_foreach; -mod frag_iter_foreach_wide; -mod get_component; -mod get_component_system; -mod heavy_compute; -mod schedule; -mod simple_insert; -mod simple_insert_unbatched; -mod simple_iter; -mod simple_iter_wide; -mod simple_iter_foreach; -mod simple_iter_foreach_wide; -mod simple_iter_sparse; -mod simple_iter_sparse_wide; -mod simple_iter_sparse_foreach; -mod simple_iter_sparse_foreach_wide; -mod simple_iter_system; -mod sparse_frag_iter; -mod sparse_frag_iter_wide; -mod sparse_frag_iter_foreach; -mod sparse_frag_iter_foreach_wide; - -fn bench_simple_insert(c: &mut Criterion) { - let mut group = c.benchmark_group("simple_insert"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("base", |b| { - let mut bench = simple_insert::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("unbatched", |b| { - let mut bench = simple_insert_unbatched::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -fn bench_simple_iter(c: &mut Criterion) { - let mut group = c.benchmark_group("simple_iter"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("base", |b| { - let mut bench = simple_iter::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("wide", |b| { - let mut bench = simple_iter_wide::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("system", |b| { - let mut bench = simple_iter_system::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("sparse", |b| { - let mut bench = simple_iter_sparse::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("sparse_wide", |b| { - let mut bench = simple_iter_sparse_wide::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("foreach", |b| { - let mut bench = simple_iter_foreach::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("foreach_wide", |b| { - let mut bench = simple_iter_foreach_wide::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("sparse_foreach", |b| { - let mut bench = simple_iter_sparse_foreach::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("sparse_foreach_wide", |b| { - let mut bench = simple_iter_sparse_foreach_wide::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -fn bench_frag_iter_bc(c: &mut Criterion) { - let mut group = c.benchmark_group("fragmented_iter"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("base", |b| { - let mut bench = frag_iter::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("wide", |b| { - let mut bench = frag_iter_wide::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("foreach", |b| { - let mut bench = frag_iter_foreach::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("foreach_wide", |b| { - let mut bench = frag_iter_foreach_wide::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -fn bench_sparse_frag_iter(c: &mut Criterion) { - let mut group = c.benchmark_group("sparse_fragmented_iter"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("base", |b| { - let mut bench = sparse_frag_iter::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("wide", |b| { - let mut bench = sparse_frag_iter_wide::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("foreach", |b| { - let mut bench = sparse_frag_iter_foreach::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("foreach_wide", |b| { - let mut bench = sparse_frag_iter_foreach_wide::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -fn bench_schedule(c: &mut Criterion) { - let mut group = c.benchmark_group("schedule"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("base", |b| { - let mut bench = schedule::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -fn bench_heavy_compute(c: &mut Criterion) { - let mut group = c.benchmark_group("heavy_compute"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("base", |b| { - let mut bench = heavy_compute::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -fn bench_add_remove(c: &mut Criterion) { - let mut group = c.benchmark_group("add_remove_component"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("table", |b| { - let mut bench = add_remove_table::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("sparse_set", |b| { - let mut bench = add_remove_sparse_set::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -fn bench_add_remove_big(c: &mut Criterion) { - let mut group = c.benchmark_group("add_remove_component_big"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("table", |b| { - let mut bench = add_remove_big_table::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("sparse_set", |b| { - let mut bench = add_remove_big_sparse_set::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -fn bench_get_component(c: &mut Criterion) { - let mut group = c.benchmark_group("get_component"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); - group.bench_function("base", |b| { - let mut bench = get_component::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.bench_function("system", |b| { - let mut bench = get_component_system::Benchmark::new(); - b.iter(move || bench.run()); - }); - group.finish(); -} - -criterion_group!( - benchmarks, - bench_simple_insert, - bench_simple_iter, - bench_frag_iter_bc, - bench_sparse_frag_iter, - bench_schedule, - bench_heavy_compute, - bench_add_remove, - bench_add_remove_big, - bench_get_component, -); -criterion_main!(benchmarks); diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/schedule.rs b/benches/benches/bevy_ecs/ecs_bench_suite/schedule.rs deleted file mode 100644 index dcd1fc7d3ac0a..0000000000000 --- a/benches/benches/bevy_ecs/ecs_bench_suite/schedule.rs +++ /dev/null @@ -1,58 +0,0 @@ -use bevy_ecs::prelude::*; - -#[derive(Component)] -struct A(f32); -#[derive(Component)] -struct B(f32); -#[derive(Component)] -struct C(f32); -#[derive(Component)] -struct D(f32); -#[derive(Component)] -struct E(f32); - -fn ab(mut query: Query<(&mut A, &mut B)>) { - query.for_each_mut(|(mut a, mut b)| { - std::mem::swap(&mut a.0, &mut b.0); - }); -} - -fn cd(mut query: Query<(&mut C, &mut D)>) { - query.for_each_mut(|(mut c, mut d)| { - std::mem::swap(&mut c.0, &mut d.0); - }); -} - -fn ce(mut query: Query<(&mut C, &mut E)>) { - query.for_each_mut(|(mut c, mut e)| { - std::mem::swap(&mut c.0, &mut e.0); - }); -} - -pub struct Benchmark(World, SystemStage); - -impl Benchmark { - pub fn new() -> Self { - let mut world = World::default(); - - world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0)))); - - world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0)))); - - world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), D(0.0)))); - - world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), E(0.0)))); - - let mut stage = SystemStage::parallel(); - stage.add_system(ab); - stage.add_system(cd); - stage.add_system(ce); - stage.run(&mut world); - - Self(world, stage) - } - - pub fn run(&mut self) { - self.1.run(&mut self.0); - } -} diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/heavy_compute.rs b/benches/benches/bevy_ecs/iteration/heavy_compute.rs similarity index 59% rename from benches/benches/bevy_ecs/ecs_bench_suite/heavy_compute.rs rename to benches/benches/bevy_ecs/iteration/heavy_compute.rs index 169f32f06500e..440d1bcb22f6f 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/heavy_compute.rs +++ b/benches/benches/bevy_ecs/iteration/heavy_compute.rs @@ -1,23 +1,25 @@ use bevy_ecs::prelude::*; use bevy_tasks::{ComputeTaskPool, TaskPool}; +use criterion::Criterion; use glam::*; -#[derive(Component, Copy, Clone)] -struct Position(Vec3); +pub fn heavy_compute(c: &mut Criterion) { + #[derive(Component, Copy, Clone)] + struct Position(Vec3); -#[derive(Component, Copy, Clone)] -struct Rotation(Vec3); + #[derive(Component, Copy, Clone)] + struct Rotation(Vec3); -#[derive(Component, Copy, Clone)] -struct Velocity(Vec3); + #[derive(Component, Copy, Clone)] + struct Velocity(Vec3); -#[derive(Component, Copy, Clone)] -struct Transform(Mat4); + #[derive(Component, Copy, Clone)] + struct Transform(Mat4); -pub struct Benchmark(World, Box>); - -impl Benchmark { - pub fn new() -> Self { + let mut group = c.benchmark_group("heavy_compute"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + group.bench_function("base", |b| { ComputeTaskPool::init(TaskPool::default); let mut world = World::default(); @@ -45,10 +47,7 @@ impl Benchmark { system.initialize(&mut world); system.update_archetype_component_access(&world); - Self(world, Box::new(system)) - } - - pub fn run(&mut self) { - self.1.run((), &mut self.0); - } + b.iter(move || system.run((), &mut world)); + }); + group.finish(); } diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/frag_iter.rs b/benches/benches/bevy_ecs/iteration/iter_frag.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/frag_iter.rs rename to benches/benches/bevy_ecs/iteration/iter_frag.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_foreach.rs b/benches/benches/bevy_ecs/iteration/iter_frag_foreach.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_foreach.rs rename to benches/benches/bevy_ecs/iteration/iter_frag_foreach.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter_foreach.rs b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_sparse.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter_foreach.rs rename to benches/benches/bevy_ecs/iteration/iter_frag_foreach_sparse.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_foreach_wide.rs b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide.rs similarity index 61% rename from benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_foreach_wide.rs rename to benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide.rs index ee8f93c310ea6..e955982cdd4a4 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_foreach_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide.rs @@ -7,7 +7,7 @@ macro_rules! create_entities { struct $variants(f32); for _ in 0..20 { $world.spawn().insert_bundle(( - $variants(0.0), + $variants(0.0), Data::<0>(1.0), Data::<1>(1.0), Data::<2>(1.0), @@ -28,19 +28,22 @@ macro_rules! create_entities { #[derive(Component)] struct Data(f32); -pub struct Benchmark<'w>(World, QueryState<( - &'w mut Data<0>, - &'w mut Data<1>, - &'w mut Data<2>, - &'w mut Data<3>, - &'w mut Data<4>, - &'w mut Data<5>, - &'w mut Data<6>, - &'w mut Data<7>, - &'w mut Data<8>, - &'w mut Data<9>, - &'w mut Data<10>, -)>); +pub struct Benchmark<'w>( + World, + QueryState<( + &'w mut Data<0>, + &'w mut Data<1>, + &'w mut Data<2>, + &'w mut Data<3>, + &'w mut Data<4>, + &'w mut Data<5>, + &'w mut Data<6>, + &'w mut Data<7>, + &'w mut Data<8>, + &'w mut Data<9>, + &'w mut Data<10>, + )>, +); impl<'w> Benchmark<'w> { pub fn new() -> Self { @@ -54,17 +57,17 @@ impl<'w> Benchmark<'w> { pub fn run(&mut self) { self.1.for_each_mut(&mut self.0, |mut data| { - data.0.0 *= 2.0; - data.1.0 *= 2.0; - data.2.0 *= 2.0; - data.3.0 *= 2.0; - data.4.0 *= 2.0; - data.5.0 *= 2.0; - data.6.0 *= 2.0; - data.7.0 *= 2.0; - data.8.0 *= 2.0; - data.9.0 *= 2.0; - data.10.0 *= 2.0; + data.0 .0 *= 2.0; + data.1 .0 *= 2.0; + data.2 .0 *= 2.0; + data.3 .0 *= 2.0; + data.4 .0 *= 2.0; + data.5 .0 *= 2.0; + data.6 .0 *= 2.0; + data.7 .0 *= 2.0; + data.8 .0 *= 2.0; + data.9 .0 *= 2.0; + data.10 .0 *= 2.0; }); } } diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter_foreach_wide.rs b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide_sparse.rs similarity index 73% rename from benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter_foreach_wide.rs rename to benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide_sparse.rs index e8b52de5054c1..f7d2a066f9fc7 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter_foreach_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide_sparse.rs @@ -15,19 +15,22 @@ macro_rules! create_entities { #[derive(Component)] struct Data(f32); -pub struct Benchmark<'w>(World, QueryState<( - &'w mut Data<0>, - &'w mut Data<1>, - &'w mut Data<2>, - &'w mut Data<3>, - &'w mut Data<4>, - &'w mut Data<5>, - &'w mut Data<6>, - &'w mut Data<7>, - &'w mut Data<8>, - &'w mut Data<9>, - &'w mut Data<10>, -)>); +pub struct Benchmark<'w>( + World, + QueryState<( + &'w mut Data<0>, + &'w mut Data<1>, + &'w mut Data<2>, + &'w mut Data<3>, + &'w mut Data<4>, + &'w mut Data<5>, + &'w mut Data<6>, + &'w mut Data<7>, + &'w mut Data<8>, + &'w mut Data<9>, + &'w mut Data<10>, + )>, +); impl<'w> Benchmark<'w> { pub fn new() -> Self { @@ -64,17 +67,17 @@ impl<'w> Benchmark<'w> { pub fn run(&mut self) { self.1.for_each_mut(&mut self.0, |mut data| { - data.0.0 *= 2.0; - data.1.0 *= 2.0; - data.2.0 *= 2.0; - data.3.0 *= 2.0; - data.4.0 *= 2.0; - data.5.0 *= 2.0; - data.6.0 *= 2.0; - data.7.0 *= 2.0; - data.8.0 *= 2.0; - data.9.0 *= 2.0; - data.10.0 *= 2.0; + data.0 .0 *= 2.0; + data.1 .0 *= 2.0; + data.2 .0 *= 2.0; + data.3 .0 *= 2.0; + data.4 .0 *= 2.0; + data.5 .0 *= 2.0; + data.6 .0 *= 2.0; + data.7 .0 *= 2.0; + data.8 .0 *= 2.0; + data.9 .0 *= 2.0; + data.10 .0 *= 2.0; }); } } diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter.rs b/benches/benches/bevy_ecs/iteration/iter_frag_sparse.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter.rs rename to benches/benches/bevy_ecs/iteration/iter_frag_sparse.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_wide.rs b/benches/benches/bevy_ecs/iteration/iter_frag_wide.rs similarity index 61% rename from benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_wide.rs rename to benches/benches/bevy_ecs/iteration/iter_frag_wide.rs index d7514a07d6201..024a7bfbdf450 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_wide.rs @@ -7,7 +7,7 @@ macro_rules! create_entities { struct $variants(f32); for _ in 0..20 { $world.spawn().insert_bundle(( - $variants(0.0), + $variants(0.0), Data::<0>(1.0), Data::<1>(1.0), Data::<2>(1.0), @@ -28,19 +28,22 @@ macro_rules! create_entities { #[derive(Component)] struct Data(f32); -pub struct Benchmark<'w>(World, QueryState<( - &'w mut Data<0>, - &'w mut Data<1>, - &'w mut Data<2>, - &'w mut Data<3>, - &'w mut Data<4>, - &'w mut Data<5>, - &'w mut Data<6>, - &'w mut Data<7>, - &'w mut Data<8>, - &'w mut Data<9>, - &'w mut Data<10>, -)>); +pub struct Benchmark<'w>( + World, + QueryState<( + &'w mut Data<0>, + &'w mut Data<1>, + &'w mut Data<2>, + &'w mut Data<3>, + &'w mut Data<4>, + &'w mut Data<5>, + &'w mut Data<6>, + &'w mut Data<7>, + &'w mut Data<8>, + &'w mut Data<9>, + &'w mut Data<10>, + )>, +); impl<'w> Benchmark<'w> { pub fn new() -> Self { @@ -54,17 +57,17 @@ impl<'w> Benchmark<'w> { pub fn run(&mut self) { for mut data in self.1.iter_mut(&mut self.0) { - data.0.0 *= 2.0; - data.1.0 *= 2.0; - data.2.0 *= 2.0; - data.3.0 *= 2.0; - data.4.0 *= 2.0; - data.5.0 *= 2.0; - data.6.0 *= 2.0; - data.7.0 *= 2.0; - data.8.0 *= 2.0; - data.9.0 *= 2.0; - data.10.0 *= 2.0; + data.0 .0 *= 2.0; + data.1 .0 *= 2.0; + data.2 .0 *= 2.0; + data.3 .0 *= 2.0; + data.4 .0 *= 2.0; + data.5 .0 *= 2.0; + data.6 .0 *= 2.0; + data.7 .0 *= 2.0; + data.8 .0 *= 2.0; + data.9 .0 *= 2.0; + data.10 .0 *= 2.0; } } } diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter_wide.rs b/benches/benches/bevy_ecs/iteration/iter_frag_wide_sparse.rs similarity index 73% rename from benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter_wide.rs rename to benches/benches/bevy_ecs/iteration/iter_frag_wide_sparse.rs index 8074363e4e0fc..c3393a240e338 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/sparse_frag_iter_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_wide_sparse.rs @@ -14,19 +14,22 @@ macro_rules! create_entities { #[derive(Component)] struct Data(f32); -pub struct Benchmark<'w>(World, QueryState<( - &'w mut Data<0>, - &'w mut Data<1>, - &'w mut Data<2>, - &'w mut Data<3>, - &'w mut Data<4>, - &'w mut Data<5>, - &'w mut Data<6>, - &'w mut Data<7>, - &'w mut Data<8>, - &'w mut Data<9>, - &'w mut Data<10>, -)>); +pub struct Benchmark<'w>( + World, + QueryState<( + &'w mut Data<0>, + &'w mut Data<1>, + &'w mut Data<2>, + &'w mut Data<3>, + &'w mut Data<4>, + &'w mut Data<5>, + &'w mut Data<6>, + &'w mut Data<7>, + &'w mut Data<8>, + &'w mut Data<9>, + &'w mut Data<10>, + )>, +); impl<'w> Benchmark<'w> { pub fn new() -> Self { @@ -64,17 +67,17 @@ impl<'w> Benchmark<'w> { pub fn run(&mut self) { for mut data in self.1.iter_mut(&mut self.0) { - data.0.0 *= 2.0; - data.1.0 *= 2.0; - data.2.0 *= 2.0; - data.3.0 *= 2.0; - data.4.0 *= 2.0; - data.5.0 *= 2.0; - data.6.0 *= 2.0; - data.7.0 *= 2.0; - data.8.0 *= 2.0; - data.9.0 *= 2.0; - data.10.0 *= 2.0; + data.0 .0 *= 2.0; + data.1 .0 *= 2.0; + data.2 .0 *= 2.0; + data.3 .0 *= 2.0; + data.4 .0 *= 2.0; + data.5 .0 *= 2.0; + data.6 .0 *= 2.0; + data.7 .0 *= 2.0; + data.8 .0 *= 2.0; + data.9 .0 *= 2.0; + data.10 .0 *= 2.0; } } } diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter.rs b/benches/benches/bevy_ecs/iteration/iter_simple.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter.rs rename to benches/benches/bevy_ecs/iteration/iter_simple.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_foreach.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_foreach.rs rename to benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_foreach.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_foreach.rs rename to benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_foreach_wide.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs similarity index 71% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_foreach_wide.rs rename to benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs index 3a5590baececc..a5a0cea163b89 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_foreach_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs @@ -13,18 +13,21 @@ struct Rotation(Vec3); #[derive(Component, Copy, Clone)] struct Velocity(Vec3); -pub struct Benchmark<'w>(World, QueryState<( - &'w Velocity<0>, - &'w mut Position<0>, - &'w Velocity<1>, - &'w mut Position<1>, - &'w Velocity<2>, - &'w mut Position<2>, - &'w Velocity<3>, - &'w mut Position<3>, - &'w Velocity<4>, - &'w mut Position<4>, -)>); +pub struct Benchmark<'w>( + World, + QueryState<( + &'w Velocity<0>, + &'w mut Position<0>, + &'w Velocity<1>, + &'w mut Position<1>, + &'w Velocity<2>, + &'w mut Position<2>, + &'w Velocity<3>, + &'w mut Position<3>, + &'w Velocity<4>, + &'w mut Position<4>, + )>, +); impl<'w> Benchmark<'w> { pub fn new() -> Self { @@ -54,10 +57,10 @@ impl<'w> Benchmark<'w> { pub fn run(&mut self) { self.1.for_each_mut(&mut self.0, |mut item| { - item.1.0 += item.0.0; - item.3.0 += item.2.0; - item.5.0 += item.4.0; - item.7.0 += item.6.0; + item.1 .0 += item.0 .0; + item.3 .0 += item.2 .0; + item.5 .0 += item.4 .0; + item.7 .0 += item.6 .0; }); } } diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_foreach_wide.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs similarity index 72% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_foreach_wide.rs rename to benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs index a74dea68a7b22..d357393c310b6 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_foreach_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs @@ -15,18 +15,21 @@ struct Rotation(Vec3); #[component(storage = "SparseSet")] struct Velocity(Vec3); -pub struct Benchmark<'w>(World, QueryState<( - &'w Velocity<0>, - &'w mut Position<0>, - &'w Velocity<1>, - &'w mut Position<1>, - &'w Velocity<2>, - &'w mut Position<2>, - &'w Velocity<3>, - &'w mut Position<3>, - &'w Velocity<4>, - &'w mut Position<4>, -)>); +pub struct Benchmark<'w>( + World, + QueryState<( + &'w Velocity<0>, + &'w mut Position<0>, + &'w Velocity<1>, + &'w mut Position<1>, + &'w Velocity<2>, + &'w mut Position<2>, + &'w Velocity<3>, + &'w mut Position<3>, + &'w Velocity<4>, + &'w mut Position<4>, + )>, +); impl<'w> Benchmark<'w> { pub fn new() -> Self { @@ -56,10 +59,10 @@ impl<'w> Benchmark<'w> { pub fn run(&mut self) { self.1.for_each_mut(&mut self.0, |mut item| { - item.1.0 += item.0.0; - item.3.0 += item.2.0; - item.5.0 += item.4.0; - item.7.0 += item.6.0; + item.1 .0 += item.0 .0; + item.3 .0 += item.2 .0; + item.5 .0 += item.4 .0; + item.7 .0 += item.6 .0; }); } } diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse.rs b/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse.rs rename to benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_system.rs b/benches/benches/bevy_ecs/iteration/iter_simple_system.rs similarity index 100% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_system.rs rename to benches/benches/bevy_ecs/iteration/iter_simple_system.rs diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_wide.rs b/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs similarity index 71% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_wide.rs rename to benches/benches/bevy_ecs/iteration/iter_simple_wide.rs index b4ae51d8918a4..a182531404f5f 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs @@ -13,18 +13,21 @@ struct Rotation(Vec3); #[derive(Component, Copy, Clone)] struct Velocity(Vec3); -pub struct Benchmark<'w>(World, QueryState<( - &'w Velocity<0>, - &'w mut Position<0>, - &'w Velocity<1>, - &'w mut Position<1>, - &'w Velocity<2>, - &'w mut Position<2>, - &'w Velocity<3>, - &'w mut Position<3>, - &'w Velocity<4>, - &'w mut Position<4>, -)>); +pub struct Benchmark<'w>( + World, + QueryState<( + &'w Velocity<0>, + &'w mut Position<0>, + &'w Velocity<1>, + &'w mut Position<1>, + &'w Velocity<2>, + &'w mut Position<2>, + &'w Velocity<3>, + &'w mut Position<3>, + &'w Velocity<4>, + &'w mut Position<4>, + )>, +); impl<'w> Benchmark<'w> { pub fn new() -> Self { @@ -54,10 +57,10 @@ impl<'w> Benchmark<'w> { pub fn run(&mut self) { for mut item in self.1.iter_mut(&mut self.0) { - item.1.0 += item.0.0; - item.3.0 += item.2.0; - item.5.0 += item.4.0; - item.7.0 += item.6.0; + item.1 .0 += item.0 .0; + item.3 .0 += item.2 .0; + item.5 .0 += item.4 .0; + item.7 .0 += item.6 .0; } } } diff --git a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_wide.rs b/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs similarity index 72% rename from benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_wide.rs rename to benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs index 850d82bce2870..88de1f225fd94 100644 --- a/benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs @@ -15,18 +15,21 @@ struct Rotation(Vec3); #[component(storage = "SparseSet")] struct Velocity(Vec3); -pub struct Benchmark<'w>(World, QueryState<( - &'w Velocity<0>, - &'w mut Position<0>, - &'w Velocity<1>, - &'w mut Position<1>, - &'w Velocity<2>, - &'w mut Position<2>, - &'w Velocity<3>, - &'w mut Position<3>, - &'w Velocity<4>, - &'w mut Position<4>, -)>); +pub struct Benchmark<'w>( + World, + QueryState<( + &'w Velocity<0>, + &'w mut Position<0>, + &'w Velocity<1>, + &'w mut Position<1>, + &'w Velocity<2>, + &'w mut Position<2>, + &'w Velocity<3>, + &'w mut Position<3>, + &'w Velocity<4>, + &'w mut Position<4>, + )>, +); impl<'w> Benchmark<'w> { pub fn new() -> Self { @@ -56,10 +59,10 @@ impl<'w> Benchmark<'w> { pub fn run(&mut self) { for mut item in self.1.iter_mut(&mut self.0) { - item.1.0 += item.0.0; - item.3.0 += item.2.0; - item.5.0 += item.4.0; - item.7.0 += item.6.0; + item.1 .0 += item.0 .0; + item.3 .0 += item.2 .0; + item.5 .0 += item.4 .0; + item.7 .0 += item.6 .0; } } } diff --git a/benches/benches/bevy_ecs/iteration/mod.rs b/benches/benches/bevy_ecs/iteration/mod.rs new file mode 100644 index 0000000000000..e3ed6a6afeabe --- /dev/null +++ b/benches/benches/bevy_ecs/iteration/mod.rs @@ -0,0 +1,119 @@ +use criterion::*; + +mod heavy_compute; +mod iter_frag; +mod iter_frag_foreach; +mod iter_frag_foreach_sparse; +mod iter_frag_foreach_wide; +mod iter_frag_foreach_wide_sparse; +mod iter_frag_sparse; +mod iter_frag_wide; +mod iter_frag_wide_sparse; +mod iter_simple; +mod iter_simple_foreach; +mod iter_simple_foreach_sparse_set; +mod iter_simple_foreach_wide; +mod iter_simple_foreach_wide_sparse_set; +mod iter_simple_sparse_set; +mod iter_simple_system; +mod iter_simple_wide; +mod iter_simple_wide_sparse_set; + +use heavy_compute::*; + +criterion_group!( + iterations_benches, + iter_frag, + iter_frag_sparse, + iter_simple, + heavy_compute, +); + +fn iter_simple(c: &mut Criterion) { + let mut group = c.benchmark_group("iter_simple"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + group.bench_function("base", |b| { + let mut bench = iter_simple::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("wide", |b| { + let mut bench = iter_simple_wide::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("system", |b| { + let mut bench = iter_simple_system::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("sparse_set", |b| { + let mut bench = iter_simple_sparse_set::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("wide_sparse_set", |b| { + let mut bench = iter_simple_wide_sparse_set::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("foreach", |b| { + let mut bench = iter_simple_foreach::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("foreach_wide", |b| { + let mut bench = iter_simple_foreach_wide::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("foreach_sparse_set", |b| { + let mut bench = iter_simple_foreach_sparse_set::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("foreach_wide_sparse_set", |b| { + let mut bench = iter_simple_foreach_wide_sparse_set::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.finish(); +} + +fn iter_frag(c: &mut Criterion) { + let mut group = c.benchmark_group("iter_fragmented"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + group.bench_function("base", |b| { + let mut bench = iter_frag::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("wide", |b| { + let mut bench = iter_frag_wide::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("foreach", |b| { + let mut bench = iter_frag_foreach::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("foreach_wide", |b| { + let mut bench = iter_frag_foreach_wide::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.finish(); +} + +fn iter_frag_sparse(c: &mut Criterion) { + let mut group = c.benchmark_group("iter_fragmented_sparse"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + group.bench_function("base", |b| { + let mut bench = iter_frag_sparse::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("wide", |b| { + let mut bench = iter_frag_wide_sparse::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("foreach", |b| { + let mut bench = iter_frag_foreach_sparse::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.bench_function("foreach_wide", |b| { + let mut bench = iter_frag_foreach_wide_sparse::Benchmark::new(); + b.iter(move || bench.run()); + }); + group.finish(); +} diff --git a/benches/benches/bevy_ecs/scheduling/mod.rs b/benches/benches/bevy_ecs/scheduling/mod.rs new file mode 100644 index 0000000000000..21ccc56c04f63 --- /dev/null +++ b/benches/benches/bevy_ecs/scheduling/mod.rs @@ -0,0 +1,24 @@ +use criterion::criterion_group; + +mod run_criteria; +mod schedule; +mod stages; + +use run_criteria::*; +use schedule::*; +use stages::*; + +criterion_group!( + scheduling_benches, + run_criteria_yes, + run_criteria_no, + run_criteria_yes_with_labels, + run_criteria_no_with_labels, + run_criteria_yes_with_query, + run_criteria_yes_with_resource, + empty_systems, + busy_systems, + contrived, + schedule, + build_schedule, +); diff --git a/benches/benches/bevy_ecs/run_criteria.rs b/benches/benches/bevy_ecs/scheduling/run_criteria.rs similarity index 92% rename from benches/benches/bevy_ecs/run_criteria.rs rename to benches/benches/bevy_ecs/scheduling/run_criteria.rs index 26a9ef1984e72..7a6f1e66cde47 100644 --- a/benches/benches/bevy_ecs/run_criteria.rs +++ b/benches/benches/bevy_ecs/scheduling/run_criteria.rs @@ -5,24 +5,13 @@ use bevy_ecs::{ system::Query, world::World, }; -use criterion::{criterion_group, criterion_main, Criterion}; - -criterion_group!( - benches, - run_criteria_yes, - run_criteria_no, - run_criteria_yes_with_labels, - run_criteria_no_with_labels, - run_criteria_yes_with_query, - run_criteria_yes_with_resource -); -criterion_main!(benches); +use criterion::Criterion; fn run_stage(stage: &mut SystemStage, world: &mut World) { stage.run(world); } -fn run_criteria_yes(criterion: &mut Criterion) { +pub fn run_criteria_yes(criterion: &mut Criterion) { let mut world = World::new(); let mut group = criterion.benchmark_group("run_criteria/yes"); group.warm_up_time(std::time::Duration::from_millis(500)); @@ -54,7 +43,7 @@ fn run_criteria_yes(criterion: &mut Criterion) { group.finish(); } -fn run_criteria_no(criterion: &mut Criterion) { +pub fn run_criteria_no(criterion: &mut Criterion) { let mut world = World::new(); let mut group = criterion.benchmark_group("run_criteria/no"); group.warm_up_time(std::time::Duration::from_millis(500)); @@ -85,7 +74,7 @@ fn run_criteria_no(criterion: &mut Criterion) { group.finish(); } -fn run_criteria_yes_with_labels(criterion: &mut Criterion) { +pub fn run_criteria_yes_with_labels(criterion: &mut Criterion) { let mut world = World::new(); let mut group = criterion.benchmark_group("run_criteria/yes_with_labels"); group.warm_up_time(std::time::Duration::from_millis(500)); @@ -116,7 +105,7 @@ fn run_criteria_yes_with_labels(criterion: &mut Criterion) { group.finish(); } -fn run_criteria_no_with_labels(criterion: &mut Criterion) { +pub fn run_criteria_no_with_labels(criterion: &mut Criterion) { let mut world = World::new(); let mut group = criterion.benchmark_group("run_criteria/no_with_labels"); group.warm_up_time(std::time::Duration::from_millis(500)); @@ -150,7 +139,7 @@ fn run_criteria_no_with_labels(criterion: &mut Criterion) { #[derive(Component)] struct TestBool(pub bool); -fn run_criteria_yes_with_query(criterion: &mut Criterion) { +pub fn run_criteria_yes_with_query(criterion: &mut Criterion) { let mut world = World::new(); world.spawn().insert(TestBool(true)); let mut group = criterion.benchmark_group("run_criteria/yes_using_query"); @@ -187,7 +176,7 @@ fn run_criteria_yes_with_query(criterion: &mut Criterion) { group.finish(); } -fn run_criteria_yes_with_resource(criterion: &mut Criterion) { +pub fn run_criteria_yes_with_resource(criterion: &mut Criterion) { let mut world = World::new(); world.insert_resource(TestBool(true)); let mut group = criterion.benchmark_group("run_criteria/yes_using_resource"); diff --git a/benches/benches/bevy_ecs/schedule.rs b/benches/benches/bevy_ecs/scheduling/schedule.rs similarity index 61% rename from benches/benches/bevy_ecs/schedule.rs rename to benches/benches/bevy_ecs/scheduling/schedule.rs index 0b8916e98b1e8..40f39fd8b6710 100644 --- a/benches/benches/bevy_ecs/schedule.rs +++ b/benches/benches/bevy_ecs/scheduling/schedule.rs @@ -1,11 +1,63 @@ use bevy_app::App; use bevy_ecs::prelude::*; -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::Criterion; -criterion_group!(benches, build_schedule); -criterion_main!(benches); +pub fn schedule(c: &mut Criterion) { + #[derive(Component)] + struct A(f32); + #[derive(Component)] + struct B(f32); + #[derive(Component)] + struct C(f32); + #[derive(Component)] + struct D(f32); + #[derive(Component)] + struct E(f32); -fn build_schedule(criterion: &mut Criterion) { + fn ab(mut query: Query<(&mut A, &mut B)>) { + query.for_each_mut(|(mut a, mut b)| { + std::mem::swap(&mut a.0, &mut b.0); + }); + } + + fn cd(mut query: Query<(&mut C, &mut D)>) { + query.for_each_mut(|(mut c, mut d)| { + std::mem::swap(&mut c.0, &mut d.0); + }); + } + + fn ce(mut query: Query<(&mut C, &mut E)>) { + query.for_each_mut(|(mut c, mut e)| { + std::mem::swap(&mut c.0, &mut e.0); + }); + } + + let mut group = c.benchmark_group("schedule"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + group.bench_function("base", |b| { + let mut world = World::default(); + + world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0)))); + + world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0)))); + + world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), D(0.0)))); + + world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), E(0.0)))); + + let mut stage = SystemStage::parallel(); + stage.add_system(ab); + stage.add_system(cd); + stage.add_system(ce); + stage.run(&mut world); + + b.iter(move || stage.run(&mut world)); + }); + group.finish(); +} + +pub fn build_schedule(criterion: &mut Criterion) { // empty system fn empty_system() {} diff --git a/benches/benches/bevy_ecs/stages.rs b/benches/benches/bevy_ecs/scheduling/stages.rs similarity index 94% rename from benches/benches/bevy_ecs/stages.rs rename to benches/benches/bevy_ecs/scheduling/stages.rs index 0a843eb47305e..0f258f4f99f38 100644 --- a/benches/benches/bevy_ecs/stages.rs +++ b/benches/benches/bevy_ecs/scheduling/stages.rs @@ -4,10 +4,7 @@ use bevy_ecs::{ system::Query, world::World, }; -use criterion::{criterion_group, criterion_main, Criterion}; - -criterion_group!(benches, empty_systems, busy_systems, contrived); -criterion_main!(benches); +use criterion::Criterion; fn run_stage(stage: &mut SystemStage, world: &mut World) { stage.run(world); @@ -26,7 +23,7 @@ struct E(f32); const ENTITY_BUNCH: usize = 5000; -fn empty_systems(criterion: &mut Criterion) { +pub fn empty_systems(criterion: &mut Criterion) { let mut world = World::new(); let mut group = criterion.benchmark_group("empty_systems"); group.warm_up_time(std::time::Duration::from_millis(500)); @@ -64,7 +61,7 @@ fn empty_systems(criterion: &mut Criterion) { group.finish() } -fn busy_systems(criterion: &mut Criterion) { +pub fn busy_systems(criterion: &mut Criterion) { fn ab(mut q: Query<(&mut A, &mut B)>) { q.for_each_mut(|(mut a, mut b)| { std::mem::swap(&mut a.0, &mut b.0); @@ -113,7 +110,7 @@ fn busy_systems(criterion: &mut Criterion) { group.finish() } -fn contrived(criterion: &mut Criterion) { +pub fn contrived(criterion: &mut Criterion) { fn s_0(mut q_0: Query<(&mut A, &mut B)>) { q_0.for_each_mut(|(mut c_0, mut c_1)| { std::mem::swap(&mut c_0.0, &mut c_1.0); diff --git a/benches/benches/bevy_ecs/commands.rs b/benches/benches/bevy_ecs/world/commands.rs similarity index 90% rename from benches/benches/bevy_ecs/commands.rs rename to benches/benches/bevy_ecs/world/commands.rs index e5993d98c23f7..a35e20033b00a 100644 --- a/benches/benches/bevy_ecs/commands.rs +++ b/benches/benches/bevy_ecs/world/commands.rs @@ -4,20 +4,7 @@ use bevy_ecs::{ system::{Command, CommandQueue, Commands}, world::World, }; -use criterion::{black_box, criterion_group, criterion_main, Criterion}; - -criterion_group!( - benches, - empty_commands, - spawn_commands, - insert_commands, - fake_commands, - zero_sized_commands, - medium_sized_commands, - large_sized_commands, - get_or_spawn -); -criterion_main!(benches); +use criterion::{black_box, Criterion}; #[derive(Component)] struct A; @@ -26,7 +13,7 @@ struct B; #[derive(Component)] struct C; -fn empty_commands(criterion: &mut Criterion) { +pub fn empty_commands(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("empty_commands"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -43,7 +30,7 @@ fn empty_commands(criterion: &mut Criterion) { group.finish(); } -fn spawn_commands(criterion: &mut Criterion) { +pub fn spawn_commands(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("spawn_commands"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -89,7 +76,7 @@ struct Matrix([[f32; 4]; 4]); #[derive(Default, Component)] struct Vec3([f32; 3]); -fn insert_commands(criterion: &mut Criterion) { +pub fn insert_commands(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("insert_commands"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -154,7 +141,7 @@ impl Command for FakeCommandB { } } -fn fake_commands(criterion: &mut Criterion) { +pub fn fake_commands(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("fake_commands"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -200,7 +187,7 @@ impl Default for LargeStruct { } } -fn sized_commands_impl(criterion: &mut Criterion) { +pub fn sized_commands_impl(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(format!("sized_commands_{}_bytes", std::mem::size_of::())); group.warm_up_time(std::time::Duration::from_millis(500)); @@ -225,19 +212,19 @@ fn sized_commands_impl(criterion: &mut Criterion) { group.finish(); } -fn zero_sized_commands(criterion: &mut Criterion) { +pub fn zero_sized_commands(criterion: &mut Criterion) { sized_commands_impl::>(criterion); } -fn medium_sized_commands(criterion: &mut Criterion) { +pub fn medium_sized_commands(criterion: &mut Criterion) { sized_commands_impl::>(criterion); } -fn large_sized_commands(criterion: &mut Criterion) { +pub fn large_sized_commands(criterion: &mut Criterion) { sized_commands_impl::>(criterion); } -fn get_or_spawn(criterion: &mut Criterion) { +pub fn get_or_spawn(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("get_or_spawn"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); diff --git a/benches/benches/bevy_ecs/world/mod.rs b/benches/benches/bevy_ecs/world/mod.rs new file mode 100644 index 0000000000000..dae5274dc8c25 --- /dev/null +++ b/benches/benches/bevy_ecs/world/mod.rs @@ -0,0 +1,27 @@ +use criterion::criterion_group; + +mod commands; +mod world_get; + +use commands::*; +use world_get::*; + +criterion_group!( + world_benches, + empty_commands, + spawn_commands, + insert_commands, + fake_commands, + zero_sized_commands, + medium_sized_commands, + large_sized_commands, + get_or_spawn, + world_entity, + world_get, + world_query_get, + world_query_iter, + world_query_for_each, + query_get_component_simple, + query_get_component, + query_get, +); diff --git a/benches/benches/bevy_ecs/world_get.rs b/benches/benches/bevy_ecs/world/world_get.rs similarity index 80% rename from benches/benches/bevy_ecs/world_get.rs rename to benches/benches/bevy_ecs/world/world_get.rs index 2b5c6f4e507ef..511864fa27418 100644 --- a/benches/benches/bevy_ecs/world_get.rs +++ b/benches/benches/bevy_ecs/world/world_get.rs @@ -1,26 +1,15 @@ use bevy_ecs::{ + bundle::Bundle, component::Component, entity::Entity, + prelude::*, system::{Query, SystemState}, - bundle::Bundle, world::World, }; -use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use criterion::{black_box, Criterion}; use rand::{prelude::SliceRandom, SeedableRng}; use rand_chacha::ChaCha8Rng; -criterion_group!( - benches, - world_entity, - world_get, - world_query_get, - world_query_iter, - world_query_for_each, - query_get_component, - query_get, -); -criterion_main!(benches); - #[derive(Component, Default)] #[component(storage = "Table")] struct Table(f32); @@ -52,7 +41,7 @@ fn setup_wide(entity_count: u32) -> World { black_box(world) } -fn world_entity(criterion: &mut Criterion) { +pub fn world_entity(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_entity"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -73,7 +62,7 @@ fn world_entity(criterion: &mut Criterion) { group.finish(); } -fn world_get(criterion: &mut Criterion) { +pub fn world_get(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_get"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -104,7 +93,7 @@ fn world_get(criterion: &mut Criterion) { group.finish(); } -fn world_query_get(criterion: &mut Criterion) { +pub fn world_query_get(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_query_get"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -157,37 +146,40 @@ fn world_query_get(criterion: &mut Criterion) { } }); }); - group.bench_function(format!("{}_entities_sparse_wide", entity_count), |bencher| { - let mut world = setup_wide::<( - WideSparse<0>, - WideSparse<1>, - WideSparse<2>, - WideSparse<3>, - WideSparse<4>, - WideSparse<5>, - )>(entity_count); - let mut query = world.query::<( - &WideSparse<0>, - &WideSparse<1>, - &WideSparse<2>, - &WideSparse<3>, - &WideSparse<4>, - &WideSparse<5>, - )>(); - - bencher.iter(|| { - for i in 0..entity_count { - let entity = Entity::from_raw(i); - assert!(query.get(&world, entity).is_ok()); - } - }); - }); + group.bench_function( + format!("{}_entities_sparse_wide", entity_count), + |bencher| { + let mut world = setup_wide::<( + WideSparse<0>, + WideSparse<1>, + WideSparse<2>, + WideSparse<3>, + WideSparse<4>, + WideSparse<5>, + )>(entity_count); + let mut query = world.query::<( + &WideSparse<0>, + &WideSparse<1>, + &WideSparse<2>, + &WideSparse<3>, + &WideSparse<4>, + &WideSparse<5>, + )>(); + + bencher.iter(|| { + for i in 0..entity_count { + let entity = Entity::from_raw(i); + assert!(query.get(&world, entity).is_ok()); + } + }); + }, + ); } group.finish(); } -fn world_query_iter(criterion: &mut Criterion) { +pub fn world_query_iter(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_query_iter"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -226,7 +218,7 @@ fn world_query_iter(criterion: &mut Criterion) { group.finish(); } -fn world_query_for_each(criterion: &mut Criterion) { +pub fn world_query_for_each(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_query_for_each"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -265,7 +257,49 @@ fn world_query_for_each(criterion: &mut Criterion) { group.finish(); } -fn query_get_component(criterion: &mut Criterion) { +pub fn query_get_component_simple(criterion: &mut Criterion) { + #[derive(Component)] + struct A(f32); + + let mut group = criterion.benchmark_group("query_get_component_simple"); + group.warm_up_time(std::time::Duration::from_millis(500)); + group.measurement_time(std::time::Duration::from_secs(4)); + + group.bench_function("unchecked", |bencher| { + let mut world = World::new(); + + let entity = world.spawn().insert(A(0.0)).id(); + let mut query = world.query::<&mut A>(); + + bencher.iter(|| { + for _x in 0..100000 { + let mut a = unsafe { query.get_unchecked(&mut world, entity).unwrap() }; + a.0 += 1.0; + } + }); + }); + group.bench_function("system", |bencher| { + let mut world = World::new(); + + let entity = world.spawn().insert(A(0.0)).id(); + fn query_system(In(entity): In, mut query: Query<&mut A>) { + for _ in 0..100_000 { + let mut a = query.get_mut(entity).unwrap(); + a.0 += 1.0; + } + } + + let mut system = IntoSystem::into_system(query_system); + system.initialize(&mut world); + system.update_archetype_component_access(&world); + + bencher.iter(|| system.run(entity, &mut world)); + }); + + group.finish(); +} + +pub fn query_get_component(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("query_get_component"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4)); @@ -320,7 +354,7 @@ fn query_get_component(criterion: &mut Criterion) { group.finish(); } -fn query_get(criterion: &mut Criterion) { +pub fn query_get(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("query_get"); group.warm_up_time(std::time::Duration::from_millis(500)); group.measurement_time(std::time::Duration::from_secs(4));