forked from bevyengine/bevy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wider ECS Benchmarks (bevyengine#5123)
# Objective As a part of evaluating bevyengine#4800, at the behest of @cart, it was noted that the ECS microbenchmarks all focus on singular component queries, whereas in reality most systems will have wider queries with multiple components in each. ## Solution Use const generics to add wider variants of existing benchmarks.
- Loading branch information
Showing
10 changed files
with
659 additions
and
0 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_foreach_wide.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use bevy_ecs::prelude::*; | ||
|
||
macro_rules! create_entities { | ||
($world:ident; $( $variants:ident ),*) => { | ||
$( | ||
#[derive(Component)] | ||
struct $variants(f32); | ||
for _ in 0..20 { | ||
$world.spawn().insert_bundle(( | ||
$variants(0.0), | ||
Data::<0>(1.0), | ||
Data::<1>(1.0), | ||
Data::<2>(1.0), | ||
Data::<3>(1.0), | ||
Data::<4>(1.0), | ||
Data::<5>(1.0), | ||
Data::<6>(1.0), | ||
Data::<7>(1.0), | ||
Data::<8>(1.0), | ||
Data::<9>(1.0), | ||
Data::<10>(1.0), | ||
)); | ||
} | ||
)* | ||
}; | ||
} | ||
|
||
#[derive(Component)] | ||
struct Data<const X: usize>(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>, | ||
)>); | ||
|
||
impl<'w> Benchmark<'w> { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
create_entities!(world; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z); | ||
|
||
let query = world.query(); | ||
Self(world, query) | ||
} | ||
|
||
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; | ||
}); | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
benches/benches/bevy_ecs/ecs_bench_suite/frag_iter_wide.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use bevy_ecs::prelude::*; | ||
|
||
macro_rules! create_entities { | ||
($world:ident; $( $variants:ident ),*) => { | ||
$( | ||
#[derive(Component)] | ||
struct $variants(f32); | ||
for _ in 0..20 { | ||
$world.spawn().insert_bundle(( | ||
$variants(0.0), | ||
Data::<0>(1.0), | ||
Data::<1>(1.0), | ||
Data::<2>(1.0), | ||
Data::<3>(1.0), | ||
Data::<4>(1.0), | ||
Data::<5>(1.0), | ||
Data::<6>(1.0), | ||
Data::<7>(1.0), | ||
Data::<8>(1.0), | ||
Data::<9>(1.0), | ||
Data::<10>(1.0), | ||
)); | ||
} | ||
)* | ||
}; | ||
} | ||
|
||
#[derive(Component)] | ||
struct Data<const X: usize>(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>, | ||
)>); | ||
|
||
impl<'w> Benchmark<'w> { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
create_entities!(world; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z); | ||
|
||
let query = world.query(); | ||
Self(world, query) | ||
} | ||
|
||
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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_foreach_wide.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use bevy_ecs::prelude::*; | ||
use glam::*; | ||
|
||
#[derive(Component, Copy, Clone)] | ||
struct Transform(Mat4); | ||
|
||
#[derive(Component, Copy, Clone)] | ||
struct Position<const X: usize>(Vec3); | ||
|
||
#[derive(Component, Copy, Clone)] | ||
struct Rotation(Vec3); | ||
|
||
#[derive(Component, Copy, Clone)] | ||
struct Velocity<const X: usize>(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>, | ||
)>); | ||
|
||
impl<'w> Benchmark<'w> { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
// TODO: batch this | ||
for _ in 0..10_000 { | ||
world.spawn().insert_bundle(( | ||
Transform(Mat4::from_scale(Vec3::ONE)), | ||
Rotation(Vec3::X), | ||
Position::<0>(Vec3::X), | ||
Velocity::<0>(Vec3::X), | ||
Position::<1>(Vec3::X), | ||
Velocity::<1>(Vec3::X), | ||
Position::<2>(Vec3::X), | ||
Velocity::<2>(Vec3::X), | ||
Position::<3>(Vec3::X), | ||
Velocity::<3>(Vec3::X), | ||
Position::<4>(Vec3::X), | ||
Velocity::<4>(Vec3::X), | ||
)); | ||
} | ||
|
||
let query = world.query(); | ||
Self(world, query) | ||
} | ||
|
||
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; | ||
}); | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
benches/benches/bevy_ecs/ecs_bench_suite/simple_iter_sparse_foreach_wide.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use bevy_ecs::prelude::*; | ||
use glam::*; | ||
|
||
#[derive(Component, Copy, Clone)] | ||
struct Transform(Mat4); | ||
|
||
#[derive(Component, Copy, Clone)] | ||
#[component(storage = "SparseSet")] | ||
struct Position<const X: usize>(Vec3); | ||
|
||
#[derive(Component, Copy, Clone)] | ||
struct Rotation(Vec3); | ||
|
||
#[derive(Component, Copy, Clone)] | ||
#[component(storage = "SparseSet")] | ||
struct Velocity<const X: usize>(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>, | ||
)>); | ||
|
||
impl<'w> Benchmark<'w> { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
// TODO: batch this | ||
for _ in 0..10_000 { | ||
world.spawn().insert_bundle(( | ||
Transform(Mat4::from_scale(Vec3::ONE)), | ||
Rotation(Vec3::X), | ||
Position::<0>(Vec3::X), | ||
Velocity::<0>(Vec3::X), | ||
Position::<1>(Vec3::X), | ||
Velocity::<1>(Vec3::X), | ||
Position::<2>(Vec3::X), | ||
Velocity::<2>(Vec3::X), | ||
Position::<3>(Vec3::X), | ||
Velocity::<3>(Vec3::X), | ||
Position::<4>(Vec3::X), | ||
Velocity::<4>(Vec3::X), | ||
)); | ||
} | ||
|
||
let query = world.query(); | ||
Self(world, query) | ||
} | ||
|
||
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; | ||
}); | ||
} | ||
} |
Oops, something went wrong.