mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
Add a random access get_component benchmark (#4607)
# Objective Add a benchmark to measure the performance of get_component, particularly for cases involving random access. Enables #2965
This commit is contained in:
parent
4e547ded11
commit
87991c50f1
2 changed files with 120 additions and 1 deletions
|
@ -8,6 +8,8 @@ license = "MIT OR Apache-2.0"
|
|||
|
||||
[dev-dependencies]
|
||||
glam = "0.20"
|
||||
rand = "0.8"
|
||||
rand_chacha = "0.3"
|
||||
criterion = { version = "0.3", features = ["html_reports"] }
|
||||
bevy_ecs = { path = "../crates/bevy_ecs" }
|
||||
bevy_tasks = { path = "../crates/bevy_tasks" }
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
use bevy_ecs::{component::Component, entity::Entity, world::World};
|
||||
use bevy_ecs::{
|
||||
component::Component,
|
||||
entity::Entity,
|
||||
system::{Query, SystemState},
|
||||
world::World,
|
||||
};
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use rand::{prelude::SliceRandom, SeedableRng};
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
|
@ -8,6 +15,8 @@ criterion_group!(
|
|||
world_query_get,
|
||||
world_query_iter,
|
||||
world_query_for_each,
|
||||
query_get_component,
|
||||
query_get,
|
||||
);
|
||||
criterion_main!(benches);
|
||||
|
||||
|
@ -20,6 +29,10 @@ struct Sparse(f32);
|
|||
|
||||
const RANGE: std::ops::Range<u32> = 5..6;
|
||||
|
||||
fn deterministic_rand() -> ChaCha8Rng {
|
||||
ChaCha8Rng::seed_from_u64(42)
|
||||
}
|
||||
|
||||
fn setup<T: Component + Default>(entity_count: u32) -> World {
|
||||
let mut world = World::default();
|
||||
world.spawn_batch((0..entity_count).map(|_| (T::default(),)));
|
||||
|
@ -188,3 +201,107 @@ fn world_query_for_each(criterion: &mut Criterion) {
|
|||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
for entity_count in RANGE.map(|i| i * 10_000) {
|
||||
group.bench_function(format!("{}_entities_table", entity_count), |bencher| {
|
||||
let mut world = World::default();
|
||||
let mut entities: Vec<_> = world
|
||||
.spawn_batch((0..entity_count).map(|_| (Table::default(),)))
|
||||
.collect();
|
||||
entities.shuffle(&mut deterministic_rand());
|
||||
let mut query = SystemState::<Query<&Table>>::new(&mut world);
|
||||
let query = query.get(&world);
|
||||
|
||||
bencher.iter(|| {
|
||||
let mut count = 0;
|
||||
for comp in entities
|
||||
.iter()
|
||||
.flat_map(|&e| query.get_component::<Table>(e))
|
||||
{
|
||||
black_box(comp);
|
||||
count += 1;
|
||||
black_box(count);
|
||||
}
|
||||
assert_eq!(black_box(count), entity_count);
|
||||
});
|
||||
});
|
||||
group.bench_function(format!("{}_entities_sparse", entity_count), |bencher| {
|
||||
let mut world = World::default();
|
||||
let mut entities: Vec<_> = world
|
||||
.spawn_batch((0..entity_count).map(|_| (Sparse::default(),)))
|
||||
.collect();
|
||||
entities.shuffle(&mut deterministic_rand());
|
||||
let mut query = SystemState::<Query<&Sparse>>::new(&mut world);
|
||||
let query = query.get(&world);
|
||||
|
||||
bencher.iter(|| {
|
||||
let mut count = 0;
|
||||
for comp in entities
|
||||
.iter()
|
||||
.flat_map(|&e| query.get_component::<Sparse>(e))
|
||||
{
|
||||
black_box(comp);
|
||||
count += 1;
|
||||
black_box(count);
|
||||
}
|
||||
assert_eq!(black_box(count), entity_count);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
for entity_count in RANGE.map(|i| i * 10_000) {
|
||||
group.bench_function(format!("{}_entities_table", entity_count), |bencher| {
|
||||
let mut world = World::default();
|
||||
let mut entities: Vec<_> = world
|
||||
.spawn_batch((0..entity_count).map(|_| (Table::default(),)))
|
||||
.collect();
|
||||
entities.shuffle(&mut deterministic_rand());
|
||||
let mut query = SystemState::<Query<&Table>>::new(&mut world);
|
||||
let query = query.get(&world);
|
||||
|
||||
bencher.iter(|| {
|
||||
let mut count = 0;
|
||||
for comp in entities.iter().flat_map(|&e| query.get(e)) {
|
||||
black_box(comp);
|
||||
count += 1;
|
||||
black_box(count);
|
||||
}
|
||||
assert_eq!(black_box(count), entity_count);
|
||||
});
|
||||
});
|
||||
group.bench_function(format!("{}_entities_sparse", entity_count), |bencher| {
|
||||
let mut world = World::default();
|
||||
let mut entities: Vec<_> = world
|
||||
.spawn_batch((0..entity_count).map(|_| (Sparse::default(),)))
|
||||
.collect();
|
||||
entities.shuffle(&mut deterministic_rand());
|
||||
let mut query = SystemState::<Query<&Sparse>>::new(&mut world);
|
||||
let query = query.get(&world);
|
||||
|
||||
bencher.iter(|| {
|
||||
let mut count = 0;
|
||||
for comp in entities.iter().flat_map(|&e| query.get(e)) {
|
||||
black_box(comp);
|
||||
count += 1;
|
||||
black_box(count);
|
||||
}
|
||||
assert_eq!(black_box(count), entity_count);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue