From 6367ad4c95bea64864626e9ed281e806bccc0d16 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Tue, 1 Jul 2025 00:50:39 +0200 Subject: [PATCH] Add benchmarks for spawning and inserting bundles (#19762) # Objective - Splitted off from https://github.com/bevyengine/bevy/pull/19491 - Add some benchmarks for spawning and inserting components. Right now these are pretty short, but it's expected that they will be extended when different kinds of dynamic bundles will be implemented. --- .../benches/bevy_ecs/bundles/insert_many.rs | 67 +++++++++++++++++++ benches/benches/bevy_ecs/bundles/mod.rs | 14 ++++ .../benches/bevy_ecs/bundles/spawn_many.rs | 40 +++++++++++ .../bevy_ecs/bundles/spawn_many_zst.rs | 27 ++++++++ .../benches/bevy_ecs/bundles/spawn_one_zst.rs | 24 +++++++ benches/benches/bevy_ecs/main.rs | 2 + 6 files changed, 174 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 0000000000..2e9bfbd8b0 --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/insert_many.rs @@ -0,0 +1,67 @@ +use benches::bench; +use bevy_ecs::{component::Component, world::World}; +use criterion::Criterion; + +const ENTITY_COUNT: usize = 2_000; + +#[derive(Component)] +struct C(usize); + +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(|| { + 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)); + } + world.clear_entities(); + }); + }); + + group.bench_function("only_last", |bencher| { + let mut world = World::new(); + bencher.iter(|| { + 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)); + } + world.clear_entities(); + }); + }); + + 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 0000000000..21ef05eb3b --- /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 0000000000..bd99cf3c56 --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/spawn_many.rs @@ -0,0 +1,40 @@ +use benches::bench; +use bevy_ecs::{component::Component, world::World}; +use criterion::Criterion; + +const ENTITY_COUNT: usize = 2_000; + +#[derive(Component)] +struct C(usize); + +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(|| { + 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), + C::<14>(1), + )); + } + world.clear_entities(); + }); + }); + + 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 0000000000..b4305f9e43 --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/spawn_many_zst.rs @@ -0,0 +1,27 @@ +use benches::bench; +use bevy_ecs::{component::Component, world::World}; +use criterion::Criterion; + +const ENTITY_COUNT: usize = 2_000; + +#[derive(Component)] +struct C; + +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(|| { + for _ in 0..ENTITY_COUNT { + 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(); + }); + }); + + 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 0000000000..acb006c1c7 --- /dev/null +++ b/benches/benches/bevy_ecs/bundles/spawn_one_zst.rs @@ -0,0 +1,24 @@ +use benches::bench; +use bevy_ecs::{component::Component, world::World}; +use criterion::Criterion; + +const ENTITY_COUNT: usize = 10_000; + +#[derive(Component)] +struct A; + +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(|| { + for _ in 0..ENTITY_COUNT { + world.spawn(A); + } + world.clear_entities(); + }); + }); + + group.finish(); +} diff --git a/benches/benches/bevy_ecs/main.rs b/benches/benches/bevy_ecs/main.rs index 4a025ab829..59b4c1fd73 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,