From 2c050080c014d9587eff5a2c4b4f724a4ca0b8cd Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sat, 21 Jun 2025 11:45:48 +0200 Subject: [PATCH 1/4] Add some benchmarks for spawning and inserting bundles --- .../benches/bevy_ecs/bundles/insert_many.rs | 68 +++++++++++++++++++ benches/benches/bevy_ecs/bundles/mod.rs | 14 ++++ .../benches/bevy_ecs/bundles/spawn_many.rs | 44 ++++++++++++ .../bevy_ecs/bundles/spawn_many_zst.rs | 31 +++++++++ .../benches/bevy_ecs/bundles/spawn_one_zst.rs | 28 ++++++++ benches/benches/bevy_ecs/main.rs | 2 + 6 files changed, 187 insertions(+) create mode 100644 benches/benches/bevy_ecs/bundles/insert_many.rs create mode 100644 benches/benches/bevy_ecs/bundles/mod.rs create mode 100644 benches/benches/bevy_ecs/bundles/spawn_many.rs create mode 100644 benches/benches/bevy_ecs/bundles/spawn_many_zst.rs create mode 100644 benches/benches/bevy_ecs/bundles/spawn_one_zst.rs diff --git a/benches/benches/bevy_ecs/bundles/insert_many.rs b/benches/benches/bevy_ecs/bundles/insert_many.rs new file mode 100644 index 0000000000000..fbc0409f4d057 --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/insert_many.rs @@ -0,0 +1,68 @@ +use benches::bench; +use bevy_ecs::{component::Component, world::World}; +use criterion::Criterion; + +const ENTITY_COUNT: usize = 2_000; + +#[derive(Component)] +struct C(usize); + +#[derive(Component)] +struct W(T); + +pub fn insert_many(criterion: &mut Criterion) { + let mut group = criterion.benchmark_group(bench!("insert_many")); + + group.bench_function("all", |bencher| { + bencher.iter(|| { + let mut world = World::new(); + for _ in 0..ENTITY_COUNT { + world + .spawn_empty() + .insert(C::<0>(1)) + .insert(C::<1>(1)) + .insert(C::<2>(1)) + .insert(C::<3>(1)) + .insert(C::<4>(1)) + .insert(C::<5>(1)) + .insert(C::<6>(1)) + .insert(C::<7>(1)) + .insert(C::<8>(1)) + .insert(C::<9>(1)) + .insert(C::<10>(1)) + .insert(C::<11>(1)) + .insert(C::<12>(1)) + .insert(C::<13>(1)) + .insert(C::<14>(1)); + } + }); + }); + + group.bench_function("only_last", |bencher| { + bencher.iter(|| { + let mut world = World::new(); + for _ in 0..ENTITY_COUNT { + world + .spawn(( + C::<0>(1), + C::<1>(1), + C::<2>(1), + C::<3>(1), + C::<4>(1), + C::<5>(1), + C::<6>(1), + C::<7>(1), + C::<8>(1), + C::<9>(1), + C::<10>(1), + C::<11>(1), + C::<12>(1), + C::<13>(1), + )) + .insert(C::<14>(1)); + } + }); + }); + + group.finish(); +} diff --git a/benches/benches/bevy_ecs/bundles/mod.rs b/benches/benches/bevy_ecs/bundles/mod.rs new file mode 100644 index 0000000000000..21ef05eb3b3a2 --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/mod.rs @@ -0,0 +1,14 @@ +use criterion::criterion_group; + +mod insert_many; +mod spawn_many; +mod spawn_many_zst; +mod spawn_one_zst; + +criterion_group!( + benches, + spawn_one_zst::spawn_one_zst, + spawn_many_zst::spawn_many_zst, + spawn_many::spawn_many, + insert_many::insert_many, +); diff --git a/benches/benches/bevy_ecs/bundles/spawn_many.rs b/benches/benches/bevy_ecs/bundles/spawn_many.rs new file mode 100644 index 0000000000000..21cbf57d7709b --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/spawn_many.rs @@ -0,0 +1,44 @@ +use core::hint::black_box; + +use benches::bench; +use bevy_ecs::{component::Component, world::World}; +use criterion::Criterion; + +const ENTITY_COUNT: usize = 2_000; + +#[derive(Component)] +struct C(usize); + +#[derive(Component)] +struct W(T); + +pub fn spawn_many(criterion: &mut Criterion) { + let mut group = criterion.benchmark_group(bench!("spawn_many")); + + group.bench_function("static", |bencher| { + bencher.iter(|| { + let mut world = World::new(); + for _ in 0..ENTITY_COUNT { + world.spawn(black_box(( + C::<0>(1), + C::<1>(1), + C::<2>(1), + C::<3>(1), + C::<4>(1), + C::<5>(1), + C::<6>(1), + C::<7>(1), + C::<8>(1), + C::<9>(1), + C::<10>(1), + C::<11>(1), + C::<12>(1), + C::<13>(1), + C::<14>(1), + ))); + } + }); + }); + + group.finish(); +} diff --git a/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs new file mode 100644 index 0000000000000..a405f03fd6ba1 --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs @@ -0,0 +1,31 @@ +use core::hint::black_box; + +use benches::bench; +use bevy_ecs::{component::Component, world::World}; +use criterion::Criterion; + +const ENTITY_COUNT: usize = 2_000; + +#[derive(Component)] +struct C; + +#[derive(Component)] +struct W(T); + +pub fn spawn_many_zst(criterion: &mut Criterion) { + let mut group = criterion.benchmark_group(bench!("spawn_many_zst")); + + group.bench_function("static", |bencher| { + bencher.iter(|| { + let mut world = World::new(); + for _ in 0..ENTITY_COUNT { + world.spawn(black_box(( + C::<0>, C::<1>, C::<2>, C::<3>, C::<4>, C::<5>, C::<6>, C::<7>, C::<8>, C::<9>, + C::<10>, C::<11>, C::<12>, C::<13>, C::<14>, + ))); + } + }); + }); + + group.finish(); +} diff --git a/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs new file mode 100644 index 0000000000000..c7353685ea005 --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs @@ -0,0 +1,28 @@ +use core::hint::black_box; + +use benches::bench; +use bevy_ecs::{component::Component, world::World}; +use criterion::Criterion; + +const ENTITY_COUNT: usize = 10_000; + +#[derive(Component)] +struct A; + +#[derive(Component)] +struct B; + +pub fn spawn_one_zst(criterion: &mut Criterion) { + let mut group = criterion.benchmark_group(bench!("spawn_one_zst")); + + group.bench_function("static", |bencher| { + bencher.iter(|| { + let mut world = World::new(); + for _ in 0..ENTITY_COUNT { + world.spawn(black_box(A)); + } + }); + }); + + group.finish(); +} diff --git a/benches/benches/bevy_ecs/main.rs b/benches/benches/bevy_ecs/main.rs index 4a025ab829369..59b4c1fd7326a 100644 --- a/benches/benches/bevy_ecs/main.rs +++ b/benches/benches/bevy_ecs/main.rs @@ -5,6 +5,7 @@ use criterion::criterion_main; +mod bundles; mod change_detection; mod components; mod empty_archetypes; @@ -18,6 +19,7 @@ mod scheduling; mod world; criterion_main!( + bundles::benches, change_detection::benches, components::benches, empty_archetypes::benches, From 76dcc58d2cc87239db2b697c67b01dbd793f4a19 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sat, 21 Jun 2025 12:19:29 +0200 Subject: [PATCH 2/4] Remove unused components (for now) --- benches/benches/bevy_ecs/bundles/insert_many.rs | 3 --- benches/benches/bevy_ecs/bundles/spawn_many.rs | 3 --- benches/benches/bevy_ecs/bundles/spawn_many_zst.rs | 3 --- benches/benches/bevy_ecs/bundles/spawn_one_zst.rs | 3 --- 4 files changed, 12 deletions(-) diff --git a/benches/benches/bevy_ecs/bundles/insert_many.rs b/benches/benches/bevy_ecs/bundles/insert_many.rs index fbc0409f4d057..51716e1e02f75 100644 --- a/benches/benches/bevy_ecs/bundles/insert_many.rs +++ b/benches/benches/bevy_ecs/bundles/insert_many.rs @@ -7,9 +7,6 @@ const ENTITY_COUNT: usize = 2_000; #[derive(Component)] struct C(usize); -#[derive(Component)] -struct W(T); - pub fn insert_many(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(bench!("insert_many")); diff --git a/benches/benches/bevy_ecs/bundles/spawn_many.rs b/benches/benches/bevy_ecs/bundles/spawn_many.rs index 21cbf57d7709b..dd7314b588156 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_many.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_many.rs @@ -9,9 +9,6 @@ const ENTITY_COUNT: usize = 2_000; #[derive(Component)] struct C(usize); -#[derive(Component)] -struct W(T); - pub fn spawn_many(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(bench!("spawn_many")); diff --git a/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs index a405f03fd6ba1..3dc7abbe2bcdb 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs @@ -9,9 +9,6 @@ const ENTITY_COUNT: usize = 2_000; #[derive(Component)] struct C; -#[derive(Component)] -struct W(T); - pub fn spawn_many_zst(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(bench!("spawn_many_zst")); diff --git a/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs index c7353685ea005..0a4b74e7a0169 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs @@ -9,9 +9,6 @@ const ENTITY_COUNT: usize = 10_000; #[derive(Component)] struct A; -#[derive(Component)] -struct B; - pub fn spawn_one_zst(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(bench!("spawn_one_zst")); From 896576e1d14deebae5832a632b06a458cc3c4ef3 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 22 Jun 2025 09:48:05 +0200 Subject: [PATCH 3/4] Reuse the World in benches --- benches/benches/bevy_ecs/bundles/insert_many.rs | 6 ++++-- benches/benches/bevy_ecs/bundles/spawn_many.rs | 3 ++- benches/benches/bevy_ecs/bundles/spawn_many_zst.rs | 3 ++- benches/benches/bevy_ecs/bundles/spawn_one_zst.rs | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/benches/benches/bevy_ecs/bundles/insert_many.rs b/benches/benches/bevy_ecs/bundles/insert_many.rs index 51716e1e02f75..2e9bfbd8b009b 100644 --- a/benches/benches/bevy_ecs/bundles/insert_many.rs +++ b/benches/benches/bevy_ecs/bundles/insert_many.rs @@ -11,8 +11,8 @@ pub fn insert_many(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(bench!("insert_many")); group.bench_function("all", |bencher| { + let mut world = World::new(); bencher.iter(|| { - let mut world = World::new(); for _ in 0..ENTITY_COUNT { world .spawn_empty() @@ -32,12 +32,13 @@ pub fn insert_many(criterion: &mut Criterion) { .insert(C::<13>(1)) .insert(C::<14>(1)); } + world.clear_entities(); }); }); group.bench_function("only_last", |bencher| { + let mut world = World::new(); bencher.iter(|| { - let mut world = World::new(); for _ in 0..ENTITY_COUNT { world .spawn(( @@ -58,6 +59,7 @@ pub fn insert_many(criterion: &mut Criterion) { )) .insert(C::<14>(1)); } + world.clear_entities(); }); }); diff --git a/benches/benches/bevy_ecs/bundles/spawn_many.rs b/benches/benches/bevy_ecs/bundles/spawn_many.rs index dd7314b588156..3e5faed847bff 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_many.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_many.rs @@ -13,8 +13,8 @@ pub fn spawn_many(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(bench!("spawn_many")); group.bench_function("static", |bencher| { + let mut world = World::new(); bencher.iter(|| { - let mut world = World::new(); for _ in 0..ENTITY_COUNT { world.spawn(black_box(( C::<0>(1), @@ -34,6 +34,7 @@ pub fn spawn_many(criterion: &mut Criterion) { C::<14>(1), ))); } + world.clear_entities(); }); }); diff --git a/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs index 3dc7abbe2bcdb..1fa0b69e75b21 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs @@ -13,14 +13,15 @@ pub fn spawn_many_zst(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(bench!("spawn_many_zst")); group.bench_function("static", |bencher| { + let mut world = World::new(); bencher.iter(|| { - let mut world = World::new(); for _ in 0..ENTITY_COUNT { world.spawn(black_box(( C::<0>, C::<1>, C::<2>, C::<3>, C::<4>, C::<5>, C::<6>, C::<7>, C::<8>, C::<9>, C::<10>, C::<11>, C::<12>, C::<13>, C::<14>, ))); } + world.clear_entities(); }); }); diff --git a/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs index 0a4b74e7a0169..585eb0f3692e1 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs @@ -13,11 +13,12 @@ pub fn spawn_one_zst(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(bench!("spawn_one_zst")); group.bench_function("static", |bencher| { + let mut world = World::new(); bencher.iter(|| { - let mut world = World::new(); for _ in 0..ENTITY_COUNT { world.spawn(black_box(A)); } + world.clear_entities(); }); }); From ec225c3e7c2fe5ad660c8c61ac4729e15b237ca2 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 22 Jun 2025 09:49:44 +0200 Subject: [PATCH 4/4] Remove black_boxes --- benches/benches/bevy_ecs/bundles/spawn_many.rs | 6 ++---- benches/benches/bevy_ecs/bundles/spawn_many_zst.rs | 6 ++---- benches/benches/bevy_ecs/bundles/spawn_one_zst.rs | 4 +--- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/benches/benches/bevy_ecs/bundles/spawn_many.rs b/benches/benches/bevy_ecs/bundles/spawn_many.rs index 3e5faed847bff..bd99cf3c56183 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_many.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_many.rs @@ -1,5 +1,3 @@ -use core::hint::black_box; - use benches::bench; use bevy_ecs::{component::Component, world::World}; use criterion::Criterion; @@ -16,7 +14,7 @@ pub fn spawn_many(criterion: &mut Criterion) { let mut world = World::new(); bencher.iter(|| { for _ in 0..ENTITY_COUNT { - world.spawn(black_box(( + world.spawn(( C::<0>(1), C::<1>(1), C::<2>(1), @@ -32,7 +30,7 @@ pub fn spawn_many(criterion: &mut Criterion) { C::<12>(1), C::<13>(1), C::<14>(1), - ))); + )); } world.clear_entities(); }); diff --git a/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs index 1fa0b69e75b21..b4305f9e43fac 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs @@ -1,5 +1,3 @@ -use core::hint::black_box; - use benches::bench; use bevy_ecs::{component::Component, world::World}; use criterion::Criterion; @@ -16,10 +14,10 @@ pub fn spawn_many_zst(criterion: &mut Criterion) { let mut world = World::new(); bencher.iter(|| { for _ in 0..ENTITY_COUNT { - world.spawn(black_box(( + world.spawn(( C::<0>, C::<1>, C::<2>, C::<3>, C::<4>, C::<5>, C::<6>, C::<7>, C::<8>, C::<9>, C::<10>, C::<11>, C::<12>, C::<13>, C::<14>, - ))); + )); } world.clear_entities(); }); diff --git a/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs index 585eb0f3692e1..acb006c1c79c8 100644 --- a/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs +++ b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs @@ -1,5 +1,3 @@ -use core::hint::black_box; - use benches::bench; use bevy_ecs::{component::Component, world::World}; use criterion::Criterion; @@ -16,7 +14,7 @@ pub fn spawn_one_zst(criterion: &mut Criterion) { let mut world = World::new(); bencher.iter(|| { for _ in 0..ENTITY_COUNT { - world.spawn(black_box(A)); + world.spawn(A); } world.clear_entities(); });