mirror of
https://github.com/bevyengine/bevy
synced 2024-12-25 12:33:07 +00:00
196 lines
5.2 KiB
Rust
196 lines
5.2 KiB
Rust
|
use criterion::*;
|
||
|
use itertools::*;
|
||
|
|
||
|
use legion::prelude::*;
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct A(f32);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct B(f32);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct C(f32);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct D(f32);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct E(f32);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct F(f32);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct Tag(f32);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct Position(f32);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct Rotation(f32);
|
||
|
|
||
|
fn create_entities(
|
||
|
world: &mut World,
|
||
|
variants: &mut [Box<dyn FnMut(Entity, &mut World)>],
|
||
|
num_components: usize,
|
||
|
count: usize,
|
||
|
) {
|
||
|
let len_variants = variants.len();
|
||
|
let components = (0..)
|
||
|
.flat_map(|step| (0..len_variants).map(move |i| (i + i * step) % len_variants))
|
||
|
.chunks(num_components);
|
||
|
|
||
|
for initializers in (&components).into_iter().take(count) {
|
||
|
let entity = world.insert((), Some((A(0.0),)))[0];
|
||
|
for i in initializers {
|
||
|
let init = variants.get_mut(i).unwrap();
|
||
|
init(entity, world);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn add_background_entities(world: &mut World, count: usize) {
|
||
|
create_entities(
|
||
|
world,
|
||
|
&mut [
|
||
|
Box::new(|e, w| w.add_component(e, A(0.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_component(e, B(0.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_component(e, C(0.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_tag(e, Tag(0.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_component(e, D(0.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_tag(e, Tag(1.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_component(e, E(0.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_tag(e, Tag(2.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_component(e, F(0.0)).unwrap()),
|
||
|
Box::new(|e, w| w.add_tag(e, Tag(3.0)).unwrap()),
|
||
|
],
|
||
|
5,
|
||
|
count,
|
||
|
);
|
||
|
}
|
||
|
|
||
|
fn setup(n: usize) -> World {
|
||
|
let universe = Universe::new();
|
||
|
let mut world = universe.create_world();
|
||
|
|
||
|
world.insert((), (0..n).map(|_| (Position(0.), Rotation(0.))));
|
||
|
|
||
|
world
|
||
|
}
|
||
|
|
||
|
fn bench_create_delete(c: &mut Criterion) {
|
||
|
c.bench_function_over_inputs(
|
||
|
"create-delete",
|
||
|
|b, count| {
|
||
|
let mut world = setup(0);
|
||
|
b.iter(|| {
|
||
|
let entities = world
|
||
|
.insert((), (0..*count).map(|_| (Position(0.),)))
|
||
|
.to_vec();
|
||
|
|
||
|
for e in entities {
|
||
|
world.delete(e);
|
||
|
}
|
||
|
})
|
||
|
},
|
||
|
(0..10).map(|i| i * 100),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
fn bench_iter_simple(c: &mut Criterion) {
|
||
|
c.bench_function("iter-simple", |b| {
|
||
|
let mut world = setup(2000);
|
||
|
add_background_entities(&mut world, 10000);
|
||
|
|
||
|
let query = <(Read<Position>, Write<Rotation>)>::query();
|
||
|
|
||
|
b.iter(|| {
|
||
|
for (pos, mut rot) in query.iter_mut(&mut world) {
|
||
|
rot.0 = pos.0;
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
fn bench_iter_complex(c: &mut Criterion) {
|
||
|
c.bench_function("iter-complex", |b| {
|
||
|
let mut world = setup(0);
|
||
|
add_background_entities(&mut world, 10000);
|
||
|
|
||
|
for i in 0..200 {
|
||
|
world.insert(
|
||
|
(Tag(i as f32),),
|
||
|
(0..2000).map(|_| (Position(0.), Rotation(0.))),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
let query = <(Read<Position>, Write<Rotation>)>::query()
|
||
|
.filter(!component::<A>() & tag_value(&Tag(2.0)));
|
||
|
|
||
|
b.iter(|| {
|
||
|
for (pos, mut rot) in query.iter_mut(&mut world) {
|
||
|
rot.0 = pos.0;
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
fn bench_iter_chunks_simple(c: &mut Criterion) {
|
||
|
c.bench_function("iter-chunks-simple", |b| {
|
||
|
let mut world = setup(10000);
|
||
|
add_background_entities(&mut world, 10000);
|
||
|
|
||
|
let query = <(Write<Position>, Read<Rotation>)>::query();
|
||
|
|
||
|
b.iter(|| {
|
||
|
for c in query.iter_chunks_mut(&mut world) {
|
||
|
unsafe {
|
||
|
c.components_mut::<Position>()
|
||
|
.unwrap()
|
||
|
.get_unchecked_mut(0)
|
||
|
.0 = 0.0
|
||
|
};
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
fn bench_iter_chunks_complex(c: &mut Criterion) {
|
||
|
c.bench_function("iter-chunks-complex", |b| {
|
||
|
let mut world = setup(0);
|
||
|
add_background_entities(&mut world, 10000);
|
||
|
|
||
|
for i in 0..200 {
|
||
|
world.insert(
|
||
|
(Tag(i as f32),),
|
||
|
(0..10000).map(|_| (Position(0.), Rotation(0.))),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
let query = <(Write<Position>, Read<Rotation>)>::query()
|
||
|
.filter(!component::<A>() & tag_value(&Tag(2.0)));
|
||
|
|
||
|
b.iter(|| {
|
||
|
for c in query.iter_chunks_mut(&mut world) {
|
||
|
unsafe {
|
||
|
c.components_mut::<Position>()
|
||
|
.unwrap()
|
||
|
.get_unchecked_mut(0)
|
||
|
.0 = 0.0
|
||
|
};
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
criterion_group!(
|
||
|
basic,
|
||
|
bench_create_delete,
|
||
|
bench_iter_simple,
|
||
|
bench_iter_complex,
|
||
|
bench_iter_chunks_simple,
|
||
|
bench_iter_chunks_complex
|
||
|
);
|
||
|
criterion_main!(basic);
|