mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +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]
|
[dev-dependencies]
|
||||||
glam = "0.20"
|
glam = "0.20"
|
||||||
|
rand = "0.8"
|
||||||
|
rand_chacha = "0.3"
|
||||||
criterion = { version = "0.3", features = ["html_reports"] }
|
criterion = { version = "0.3", features = ["html_reports"] }
|
||||||
bevy_ecs = { path = "../crates/bevy_ecs" }
|
bevy_ecs = { path = "../crates/bevy_ecs" }
|
||||||
bevy_tasks = { path = "../crates/bevy_tasks" }
|
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 criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
|
use rand::{prelude::SliceRandom, SeedableRng};
|
||||||
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
criterion_group!(
|
criterion_group!(
|
||||||
benches,
|
benches,
|
||||||
|
@ -8,6 +15,8 @@ criterion_group!(
|
||||||
world_query_get,
|
world_query_get,
|
||||||
world_query_iter,
|
world_query_iter,
|
||||||
world_query_for_each,
|
world_query_for_each,
|
||||||
|
query_get_component,
|
||||||
|
query_get,
|
||||||
);
|
);
|
||||||
criterion_main!(benches);
|
criterion_main!(benches);
|
||||||
|
|
||||||
|
@ -20,6 +29,10 @@ struct Sparse(f32);
|
||||||
|
|
||||||
const RANGE: std::ops::Range<u32> = 5..6;
|
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 {
|
fn setup<T: Component + Default>(entity_count: u32) -> World {
|
||||||
let mut world = World::default();
|
let mut world = World::default();
|
||||||
world.spawn_batch((0..entity_count).map(|_| (T::default(),)));
|
world.spawn_batch((0..entity_count).map(|_| (T::default(),)));
|
||||||
|
@ -188,3 +201,107 @@ fn world_query_for_each(criterion: &mut Criterion) {
|
||||||
|
|
||||||
group.finish();
|
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