ECS benchmarks organization (#5189)

## Objective

Fixes: #5110

## Solution

- Moved benches into separate modules according to the part of ECS they are testing.
- Made so all ECS benches are included in one `benches.rs` so they don’t need to be added separately in `Cargo.toml`.
- Renamed a bunch of files to have more coherent names.
- Merged `schedule.rs` and `system_schedule.rs` into one file.
This commit is contained in:
ShadowCurse 2022-07-04 14:17:45 +00:00
parent 050251da5a
commit 179f719553
41 changed files with 612 additions and 639 deletions

View file

@ -18,38 +18,8 @@ bevy_tasks = { path = "../crates/bevy_tasks" }
bevy_utils = { path = "../crates/bevy_utils" }
[[bench]]
name = "archetype_updates"
path = "benches/bevy_ecs/archetype_updates.rs"
harness = false
[[bench]]
name = "ecs_bench_suite"
path = "benches/bevy_ecs/ecs_bench_suite/mod.rs"
harness = false
[[bench]]
name = "run_criteria"
path = "benches/bevy_ecs/run_criteria.rs"
harness = false
[[bench]]
name = "commands"
path = "benches/bevy_ecs/commands.rs"
harness = false
[[bench]]
name = "system_stage"
path = "benches/bevy_ecs/stages.rs"
harness = false
[[bench]]
name = "world_get"
path = "benches/bevy_ecs/world_get.rs"
harness = false
[[bench]]
name = "schedule"
path = "benches/bevy_ecs/schedule.rs"
name = "ecs"
path = "benches/bevy_ecs/benches.rs"
harness = false
[[bench]]

View file

@ -0,0 +1,13 @@
use criterion::criterion_main;
mod components;
mod iteration;
mod scheduling;
mod world;
criterion_main!(
iteration::iterations_benches,
components::components_benches,
scheduling::scheduling_benches,
world::world_benches,
);

View file

@ -3,10 +3,7 @@ use bevy_ecs::{
schedule::{Stage, SystemStage},
world::World,
};
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
criterion_group!(benches, no_archetypes, added_archetypes);
criterion_main!(benches);
use criterion::{BenchmarkId, Criterion};
#[derive(Component)]
struct A<const N: u16>(f32);
@ -77,7 +74,7 @@ fn add_archetypes(world: &mut World, count: u16) {
}
}
fn no_archetypes(criterion: &mut Criterion) {
pub fn no_archetypes(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("no_archetypes");
for i in 0..=5 {
let system_count = i * 20;
@ -94,7 +91,7 @@ fn no_archetypes(criterion: &mut Criterion) {
}
}
fn added_archetypes(criterion: &mut Criterion) {
pub fn added_archetypes(criterion: &mut Criterion) {
const SYSTEM_COUNT: usize = 100;
let mut group = criterion.benchmark_group("added_archetypes");
for archetype_count in [100, 200, 500, 1000, 2000, 5000, 10000] {

View file

@ -0,0 +1,65 @@
use criterion::*;
mod add_remove_big_sparse_set;
mod add_remove_big_table;
mod add_remove_sparse_set;
mod add_remove_table;
mod archetype_updates;
mod insert_simple;
mod insert_simple_unbatched;
use archetype_updates::*;
criterion_group!(
components_benches,
add_remove,
add_remove_big,
insert_simple,
no_archetypes,
added_archetypes,
);
fn add_remove(c: &mut Criterion) {
let mut group = c.benchmark_group("add_remove");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("table", |b| {
let mut bench = add_remove_table::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse_set", |b| {
let mut bench = add_remove_sparse_set::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn add_remove_big(c: &mut Criterion) {
let mut group = c.benchmark_group("add_remove_big");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("table", |b| {
let mut bench = add_remove_big_table::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse_set", |b| {
let mut bench = add_remove_big_sparse_set::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn insert_simple(c: &mut Criterion) {
let mut group = c.benchmark_group("insert_simple");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = insert_simple::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("unbatched", |b| {
let mut bench = insert_simple_unbatched::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}

View file

@ -1,23 +0,0 @@
use bevy_ecs::prelude::*;
#[derive(Component)]
struct A(f32);
pub struct Benchmark<'w>(World, Entity, QueryState<&'w mut A>);
impl<'w> Benchmark<'w> {
pub fn new() -> Self {
let mut world = World::new();
let entity = world.spawn().insert(A(0.0)).id();
let query = world.query::<&mut A>();
Self(world, entity, query)
}
pub fn run(&mut self) {
for _x in 0..100000 {
let mut a = unsafe { self.2.get_unchecked(&mut self.0, self.1).unwrap() };
a.0 += 1.0;
}
}
}

View file

@ -1,29 +0,0 @@
use bevy_ecs::prelude::*;
#[derive(Component)]
struct A(f32);
pub struct Benchmark(World, Entity, Box<dyn System<In = Entity, Out = ()>>);
impl Benchmark {
pub fn new() -> Self {
let mut world = World::new();
let entity = world.spawn().insert(A(0.0)).id();
fn query_system(In(entity): In<Entity>, mut query: Query<&mut A>) {
for _ in 0..100_000 {
let mut a = query.get_mut(entity).unwrap();
a.0 += 1.0;
}
}
let mut system = IntoSystem::into_system(query_system);
system.initialize(&mut world);
system.update_archetype_component_access(&world);
Self(world, entity, Box::new(system))
}
pub fn run(&mut self) {
self.2.run(self.1, &mut self.0);
}
}

View file

@ -1,214 +0,0 @@
use criterion::*;
mod add_remove_big_sparse_set;
mod add_remove_big_table;
mod add_remove_sparse_set;
mod add_remove_table;
mod frag_iter;
mod frag_iter_wide;
mod frag_iter_foreach;
mod frag_iter_foreach_wide;
mod get_component;
mod get_component_system;
mod heavy_compute;
mod schedule;
mod simple_insert;
mod simple_insert_unbatched;
mod simple_iter;
mod simple_iter_wide;
mod simple_iter_foreach;
mod simple_iter_foreach_wide;
mod simple_iter_sparse;
mod simple_iter_sparse_wide;
mod simple_iter_sparse_foreach;
mod simple_iter_sparse_foreach_wide;
mod simple_iter_system;
mod sparse_frag_iter;
mod sparse_frag_iter_wide;
mod sparse_frag_iter_foreach;
mod sparse_frag_iter_foreach_wide;
fn bench_simple_insert(c: &mut Criterion) {
let mut group = c.benchmark_group("simple_insert");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = simple_insert::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("unbatched", |b| {
let mut bench = simple_insert_unbatched::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn bench_simple_iter(c: &mut Criterion) {
let mut group = c.benchmark_group("simple_iter");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = simple_iter::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("wide", |b| {
let mut bench = simple_iter_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("system", |b| {
let mut bench = simple_iter_system::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse", |b| {
let mut bench = simple_iter_sparse::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse_wide", |b| {
let mut bench = simple_iter_sparse_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach", |b| {
let mut bench = simple_iter_foreach::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach_wide", |b| {
let mut bench = simple_iter_foreach_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse_foreach", |b| {
let mut bench = simple_iter_sparse_foreach::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse_foreach_wide", |b| {
let mut bench = simple_iter_sparse_foreach_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn bench_frag_iter_bc(c: &mut Criterion) {
let mut group = c.benchmark_group("fragmented_iter");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = frag_iter::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("wide", |b| {
let mut bench = frag_iter_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach", |b| {
let mut bench = frag_iter_foreach::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach_wide", |b| {
let mut bench = frag_iter_foreach_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn bench_sparse_frag_iter(c: &mut Criterion) {
let mut group = c.benchmark_group("sparse_fragmented_iter");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = sparse_frag_iter::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("wide", |b| {
let mut bench = sparse_frag_iter_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach", |b| {
let mut bench = sparse_frag_iter_foreach::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach_wide", |b| {
let mut bench = sparse_frag_iter_foreach_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn bench_schedule(c: &mut Criterion) {
let mut group = c.benchmark_group("schedule");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = schedule::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn bench_heavy_compute(c: &mut Criterion) {
let mut group = c.benchmark_group("heavy_compute");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = heavy_compute::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn bench_add_remove(c: &mut Criterion) {
let mut group = c.benchmark_group("add_remove_component");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("table", |b| {
let mut bench = add_remove_table::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse_set", |b| {
let mut bench = add_remove_sparse_set::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn bench_add_remove_big(c: &mut Criterion) {
let mut group = c.benchmark_group("add_remove_component_big");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("table", |b| {
let mut bench = add_remove_big_table::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse_set", |b| {
let mut bench = add_remove_big_sparse_set::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn bench_get_component(c: &mut Criterion) {
let mut group = c.benchmark_group("get_component");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = get_component::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("system", |b| {
let mut bench = get_component_system::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
criterion_group!(
benchmarks,
bench_simple_insert,
bench_simple_iter,
bench_frag_iter_bc,
bench_sparse_frag_iter,
bench_schedule,
bench_heavy_compute,
bench_add_remove,
bench_add_remove_big,
bench_get_component,
);
criterion_main!(benchmarks);

View file

@ -1,58 +0,0 @@
use bevy_ecs::prelude::*;
#[derive(Component)]
struct A(f32);
#[derive(Component)]
struct B(f32);
#[derive(Component)]
struct C(f32);
#[derive(Component)]
struct D(f32);
#[derive(Component)]
struct E(f32);
fn ab(mut query: Query<(&mut A, &mut B)>) {
query.for_each_mut(|(mut a, mut b)| {
std::mem::swap(&mut a.0, &mut b.0);
});
}
fn cd(mut query: Query<(&mut C, &mut D)>) {
query.for_each_mut(|(mut c, mut d)| {
std::mem::swap(&mut c.0, &mut d.0);
});
}
fn ce(mut query: Query<(&mut C, &mut E)>) {
query.for_each_mut(|(mut c, mut e)| {
std::mem::swap(&mut c.0, &mut e.0);
});
}
pub struct Benchmark(World, SystemStage);
impl Benchmark {
pub fn new() -> Self {
let mut world = World::default();
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0))));
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0))));
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), D(0.0))));
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), E(0.0))));
let mut stage = SystemStage::parallel();
stage.add_system(ab);
stage.add_system(cd);
stage.add_system(ce);
stage.run(&mut world);
Self(world, stage)
}
pub fn run(&mut self) {
self.1.run(&mut self.0);
}
}

View file

@ -1,23 +1,25 @@
use bevy_ecs::prelude::*;
use bevy_tasks::{ComputeTaskPool, TaskPool};
use criterion::Criterion;
use glam::*;
#[derive(Component, Copy, Clone)]
struct Position(Vec3);
pub fn heavy_compute(c: &mut Criterion) {
#[derive(Component, Copy, Clone)]
struct Position(Vec3);
#[derive(Component, Copy, Clone)]
struct Rotation(Vec3);
#[derive(Component, Copy, Clone)]
struct Rotation(Vec3);
#[derive(Component, Copy, Clone)]
struct Velocity(Vec3);
#[derive(Component, Copy, Clone)]
struct Velocity(Vec3);
#[derive(Component, Copy, Clone)]
struct Transform(Mat4);
#[derive(Component, Copy, Clone)]
struct Transform(Mat4);
pub struct Benchmark(World, Box<dyn System<In = (), Out = ()>>);
impl Benchmark {
pub fn new() -> Self {
let mut group = c.benchmark_group("heavy_compute");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
ComputeTaskPool::init(TaskPool::default);
let mut world = World::default();
@ -45,10 +47,7 @@ impl Benchmark {
system.initialize(&mut world);
system.update_archetype_component_access(&world);
Self(world, Box::new(system))
}
pub fn run(&mut self) {
self.1.run((), &mut self.0);
}
b.iter(move || system.run((), &mut world));
});
group.finish();
}

View file

@ -7,7 +7,7 @@ macro_rules! create_entities {
struct $variants(f32);
for _ in 0..20 {
$world.spawn().insert_bundle((
$variants(0.0),
$variants(0.0),
Data::<0>(1.0),
Data::<1>(1.0),
Data::<2>(1.0),
@ -28,19 +28,22 @@ macro_rules! create_entities {
#[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>,
)>);
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 {
@ -54,17 +57,17 @@ impl<'w> Benchmark<'w> {
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;
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;
});
}
}

View file

@ -15,19 +15,22 @@ macro_rules! create_entities {
#[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>,
)>);
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 {
@ -64,17 +67,17 @@ impl<'w> Benchmark<'w> {
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;
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;
});
}
}

View file

@ -7,7 +7,7 @@ macro_rules! create_entities {
struct $variants(f32);
for _ in 0..20 {
$world.spawn().insert_bundle((
$variants(0.0),
$variants(0.0),
Data::<0>(1.0),
Data::<1>(1.0),
Data::<2>(1.0),
@ -28,19 +28,22 @@ macro_rules! create_entities {
#[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>,
)>);
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 {
@ -54,17 +57,17 @@ impl<'w> Benchmark<'w> {
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;
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;
}
}
}

View file

@ -14,19 +14,22 @@ macro_rules! create_entities {
#[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>,
)>);
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 {
@ -64,17 +67,17 @@ impl<'w> Benchmark<'w> {
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;
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;
}
}
}

View file

@ -13,18 +13,21 @@ 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>,
)>);
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 {
@ -54,10 +57,10 @@ impl<'w> Benchmark<'w> {
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;
item.1 .0 += item.0 .0;
item.3 .0 += item.2 .0;
item.5 .0 += item.4 .0;
item.7 .0 += item.6 .0;
});
}
}

View file

@ -15,18 +15,21 @@ struct Rotation(Vec3);
#[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>,
)>);
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 {
@ -56,10 +59,10 @@ impl<'w> Benchmark<'w> {
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;
item.1 .0 += item.0 .0;
item.3 .0 += item.2 .0;
item.5 .0 += item.4 .0;
item.7 .0 += item.6 .0;
});
}
}

View file

@ -13,18 +13,21 @@ 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>,
)>);
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 {
@ -54,10 +57,10 @@ impl<'w> Benchmark<'w> {
pub fn run(&mut self) {
for mut item in self.1.iter_mut(&mut self.0) {
item.1.0 += item.0.0;
item.3.0 += item.2.0;
item.5.0 += item.4.0;
item.7.0 += item.6.0;
item.1 .0 += item.0 .0;
item.3 .0 += item.2 .0;
item.5 .0 += item.4 .0;
item.7 .0 += item.6 .0;
}
}
}

View file

@ -15,18 +15,21 @@ struct Rotation(Vec3);
#[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>,
)>);
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 {
@ -56,10 +59,10 @@ impl<'w> Benchmark<'w> {
pub fn run(&mut self) {
for mut item in self.1.iter_mut(&mut self.0) {
item.1.0 += item.0.0;
item.3.0 += item.2.0;
item.5.0 += item.4.0;
item.7.0 += item.6.0;
item.1 .0 += item.0 .0;
item.3 .0 += item.2 .0;
item.5 .0 += item.4 .0;
item.7 .0 += item.6 .0;
}
}
}

View file

@ -0,0 +1,119 @@
use criterion::*;
mod heavy_compute;
mod iter_frag;
mod iter_frag_foreach;
mod iter_frag_foreach_sparse;
mod iter_frag_foreach_wide;
mod iter_frag_foreach_wide_sparse;
mod iter_frag_sparse;
mod iter_frag_wide;
mod iter_frag_wide_sparse;
mod iter_simple;
mod iter_simple_foreach;
mod iter_simple_foreach_sparse_set;
mod iter_simple_foreach_wide;
mod iter_simple_foreach_wide_sparse_set;
mod iter_simple_sparse_set;
mod iter_simple_system;
mod iter_simple_wide;
mod iter_simple_wide_sparse_set;
use heavy_compute::*;
criterion_group!(
iterations_benches,
iter_frag,
iter_frag_sparse,
iter_simple,
heavy_compute,
);
fn iter_simple(c: &mut Criterion) {
let mut group = c.benchmark_group("iter_simple");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = iter_simple::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("wide", |b| {
let mut bench = iter_simple_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("system", |b| {
let mut bench = iter_simple_system::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("sparse_set", |b| {
let mut bench = iter_simple_sparse_set::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("wide_sparse_set", |b| {
let mut bench = iter_simple_wide_sparse_set::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach", |b| {
let mut bench = iter_simple_foreach::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach_wide", |b| {
let mut bench = iter_simple_foreach_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach_sparse_set", |b| {
let mut bench = iter_simple_foreach_sparse_set::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach_wide_sparse_set", |b| {
let mut bench = iter_simple_foreach_wide_sparse_set::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn iter_frag(c: &mut Criterion) {
let mut group = c.benchmark_group("iter_fragmented");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = iter_frag::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("wide", |b| {
let mut bench = iter_frag_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach", |b| {
let mut bench = iter_frag_foreach::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach_wide", |b| {
let mut bench = iter_frag_foreach_wide::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}
fn iter_frag_sparse(c: &mut Criterion) {
let mut group = c.benchmark_group("iter_fragmented_sparse");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut bench = iter_frag_sparse::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("wide", |b| {
let mut bench = iter_frag_wide_sparse::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach", |b| {
let mut bench = iter_frag_foreach_sparse::Benchmark::new();
b.iter(move || bench.run());
});
group.bench_function("foreach_wide", |b| {
let mut bench = iter_frag_foreach_wide_sparse::Benchmark::new();
b.iter(move || bench.run());
});
group.finish();
}

View file

@ -0,0 +1,24 @@
use criterion::criterion_group;
mod run_criteria;
mod schedule;
mod stages;
use run_criteria::*;
use schedule::*;
use stages::*;
criterion_group!(
scheduling_benches,
run_criteria_yes,
run_criteria_no,
run_criteria_yes_with_labels,
run_criteria_no_with_labels,
run_criteria_yes_with_query,
run_criteria_yes_with_resource,
empty_systems,
busy_systems,
contrived,
schedule,
build_schedule,
);

View file

@ -5,24 +5,13 @@ use bevy_ecs::{
system::Query,
world::World,
};
use criterion::{criterion_group, criterion_main, Criterion};
criterion_group!(
benches,
run_criteria_yes,
run_criteria_no,
run_criteria_yes_with_labels,
run_criteria_no_with_labels,
run_criteria_yes_with_query,
run_criteria_yes_with_resource
);
criterion_main!(benches);
use criterion::Criterion;
fn run_stage(stage: &mut SystemStage, world: &mut World) {
stage.run(world);
}
fn run_criteria_yes(criterion: &mut Criterion) {
pub fn run_criteria_yes(criterion: &mut Criterion) {
let mut world = World::new();
let mut group = criterion.benchmark_group("run_criteria/yes");
group.warm_up_time(std::time::Duration::from_millis(500));
@ -54,7 +43,7 @@ fn run_criteria_yes(criterion: &mut Criterion) {
group.finish();
}
fn run_criteria_no(criterion: &mut Criterion) {
pub fn run_criteria_no(criterion: &mut Criterion) {
let mut world = World::new();
let mut group = criterion.benchmark_group("run_criteria/no");
group.warm_up_time(std::time::Duration::from_millis(500));
@ -85,7 +74,7 @@ fn run_criteria_no(criterion: &mut Criterion) {
group.finish();
}
fn run_criteria_yes_with_labels(criterion: &mut Criterion) {
pub fn run_criteria_yes_with_labels(criterion: &mut Criterion) {
let mut world = World::new();
let mut group = criterion.benchmark_group("run_criteria/yes_with_labels");
group.warm_up_time(std::time::Duration::from_millis(500));
@ -116,7 +105,7 @@ fn run_criteria_yes_with_labels(criterion: &mut Criterion) {
group.finish();
}
fn run_criteria_no_with_labels(criterion: &mut Criterion) {
pub fn run_criteria_no_with_labels(criterion: &mut Criterion) {
let mut world = World::new();
let mut group = criterion.benchmark_group("run_criteria/no_with_labels");
group.warm_up_time(std::time::Duration::from_millis(500));
@ -150,7 +139,7 @@ fn run_criteria_no_with_labels(criterion: &mut Criterion) {
#[derive(Component)]
struct TestBool(pub bool);
fn run_criteria_yes_with_query(criterion: &mut Criterion) {
pub fn run_criteria_yes_with_query(criterion: &mut Criterion) {
let mut world = World::new();
world.spawn().insert(TestBool(true));
let mut group = criterion.benchmark_group("run_criteria/yes_using_query");
@ -187,7 +176,7 @@ fn run_criteria_yes_with_query(criterion: &mut Criterion) {
group.finish();
}
fn run_criteria_yes_with_resource(criterion: &mut Criterion) {
pub fn run_criteria_yes_with_resource(criterion: &mut Criterion) {
let mut world = World::new();
world.insert_resource(TestBool(true));
let mut group = criterion.benchmark_group("run_criteria/yes_using_resource");

View file

@ -1,11 +1,63 @@
use bevy_app::App;
use bevy_ecs::prelude::*;
use criterion::{criterion_group, criterion_main, Criterion};
use criterion::Criterion;
criterion_group!(benches, build_schedule);
criterion_main!(benches);
pub fn schedule(c: &mut Criterion) {
#[derive(Component)]
struct A(f32);
#[derive(Component)]
struct B(f32);
#[derive(Component)]
struct C(f32);
#[derive(Component)]
struct D(f32);
#[derive(Component)]
struct E(f32);
fn build_schedule(criterion: &mut Criterion) {
fn ab(mut query: Query<(&mut A, &mut B)>) {
query.for_each_mut(|(mut a, mut b)| {
std::mem::swap(&mut a.0, &mut b.0);
});
}
fn cd(mut query: Query<(&mut C, &mut D)>) {
query.for_each_mut(|(mut c, mut d)| {
std::mem::swap(&mut c.0, &mut d.0);
});
}
fn ce(mut query: Query<(&mut C, &mut E)>) {
query.for_each_mut(|(mut c, mut e)| {
std::mem::swap(&mut c.0, &mut e.0);
});
}
let mut group = c.benchmark_group("schedule");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("base", |b| {
let mut world = World::default();
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0))));
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0))));
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), D(0.0))));
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), E(0.0))));
let mut stage = SystemStage::parallel();
stage.add_system(ab);
stage.add_system(cd);
stage.add_system(ce);
stage.run(&mut world);
b.iter(move || stage.run(&mut world));
});
group.finish();
}
pub fn build_schedule(criterion: &mut Criterion) {
// empty system
fn empty_system() {}

View file

@ -4,10 +4,7 @@ use bevy_ecs::{
system::Query,
world::World,
};
use criterion::{criterion_group, criterion_main, Criterion};
criterion_group!(benches, empty_systems, busy_systems, contrived);
criterion_main!(benches);
use criterion::Criterion;
fn run_stage(stage: &mut SystemStage, world: &mut World) {
stage.run(world);
@ -26,7 +23,7 @@ struct E(f32);
const ENTITY_BUNCH: usize = 5000;
fn empty_systems(criterion: &mut Criterion) {
pub fn empty_systems(criterion: &mut Criterion) {
let mut world = World::new();
let mut group = criterion.benchmark_group("empty_systems");
group.warm_up_time(std::time::Duration::from_millis(500));
@ -64,7 +61,7 @@ fn empty_systems(criterion: &mut Criterion) {
group.finish()
}
fn busy_systems(criterion: &mut Criterion) {
pub fn busy_systems(criterion: &mut Criterion) {
fn ab(mut q: Query<(&mut A, &mut B)>) {
q.for_each_mut(|(mut a, mut b)| {
std::mem::swap(&mut a.0, &mut b.0);
@ -113,7 +110,7 @@ fn busy_systems(criterion: &mut Criterion) {
group.finish()
}
fn contrived(criterion: &mut Criterion) {
pub fn contrived(criterion: &mut Criterion) {
fn s_0(mut q_0: Query<(&mut A, &mut B)>) {
q_0.for_each_mut(|(mut c_0, mut c_1)| {
std::mem::swap(&mut c_0.0, &mut c_1.0);

View file

@ -4,20 +4,7 @@ use bevy_ecs::{
system::{Command, CommandQueue, Commands},
world::World,
};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
criterion_group!(
benches,
empty_commands,
spawn_commands,
insert_commands,
fake_commands,
zero_sized_commands,
medium_sized_commands,
large_sized_commands,
get_or_spawn
);
criterion_main!(benches);
use criterion::{black_box, Criterion};
#[derive(Component)]
struct A;
@ -26,7 +13,7 @@ struct B;
#[derive(Component)]
struct C;
fn empty_commands(criterion: &mut Criterion) {
pub fn empty_commands(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("empty_commands");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -43,7 +30,7 @@ fn empty_commands(criterion: &mut Criterion) {
group.finish();
}
fn spawn_commands(criterion: &mut Criterion) {
pub fn spawn_commands(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("spawn_commands");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -89,7 +76,7 @@ struct Matrix([[f32; 4]; 4]);
#[derive(Default, Component)]
struct Vec3([f32; 3]);
fn insert_commands(criterion: &mut Criterion) {
pub fn insert_commands(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("insert_commands");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -154,7 +141,7 @@ impl Command for FakeCommandB {
}
}
fn fake_commands(criterion: &mut Criterion) {
pub fn fake_commands(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("fake_commands");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -200,7 +187,7 @@ impl Default for LargeStruct {
}
}
fn sized_commands_impl<T: Default + Command>(criterion: &mut Criterion) {
pub fn sized_commands_impl<T: Default + Command>(criterion: &mut Criterion) {
let mut group =
criterion.benchmark_group(format!("sized_commands_{}_bytes", std::mem::size_of::<T>()));
group.warm_up_time(std::time::Duration::from_millis(500));
@ -225,19 +212,19 @@ fn sized_commands_impl<T: Default + Command>(criterion: &mut Criterion) {
group.finish();
}
fn zero_sized_commands(criterion: &mut Criterion) {
pub fn zero_sized_commands(criterion: &mut Criterion) {
sized_commands_impl::<SizedCommand<()>>(criterion);
}
fn medium_sized_commands(criterion: &mut Criterion) {
pub fn medium_sized_commands(criterion: &mut Criterion) {
sized_commands_impl::<SizedCommand<(u32, u32, u32)>>(criterion);
}
fn large_sized_commands(criterion: &mut Criterion) {
pub fn large_sized_commands(criterion: &mut Criterion) {
sized_commands_impl::<SizedCommand<LargeStruct>>(criterion);
}
fn get_or_spawn(criterion: &mut Criterion) {
pub fn get_or_spawn(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("get_or_spawn");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));

View file

@ -0,0 +1,27 @@
use criterion::criterion_group;
mod commands;
mod world_get;
use commands::*;
use world_get::*;
criterion_group!(
world_benches,
empty_commands,
spawn_commands,
insert_commands,
fake_commands,
zero_sized_commands,
medium_sized_commands,
large_sized_commands,
get_or_spawn,
world_entity,
world_get,
world_query_get,
world_query_iter,
world_query_for_each,
query_get_component_simple,
query_get_component,
query_get,
);

View file

@ -1,26 +1,15 @@
use bevy_ecs::{
bundle::Bundle,
component::Component,
entity::Entity,
prelude::*,
system::{Query, SystemState},
bundle::Bundle,
world::World,
};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{black_box, Criterion};
use rand::{prelude::SliceRandom, SeedableRng};
use rand_chacha::ChaCha8Rng;
criterion_group!(
benches,
world_entity,
world_get,
world_query_get,
world_query_iter,
world_query_for_each,
query_get_component,
query_get,
);
criterion_main!(benches);
#[derive(Component, Default)]
#[component(storage = "Table")]
struct Table(f32);
@ -52,7 +41,7 @@ fn setup_wide<T: Bundle + Default>(entity_count: u32) -> World {
black_box(world)
}
fn world_entity(criterion: &mut Criterion) {
pub fn world_entity(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("world_entity");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -73,7 +62,7 @@ fn world_entity(criterion: &mut Criterion) {
group.finish();
}
fn world_get(criterion: &mut Criterion) {
pub fn world_get(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("world_get");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -104,7 +93,7 @@ fn world_get(criterion: &mut Criterion) {
group.finish();
}
fn world_query_get(criterion: &mut Criterion) {
pub fn world_query_get(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("world_query_get");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -157,37 +146,40 @@ fn world_query_get(criterion: &mut Criterion) {
}
});
});
group.bench_function(format!("{}_entities_sparse_wide", entity_count), |bencher| {
let mut world = setup_wide::<(
WideSparse<0>,
WideSparse<1>,
WideSparse<2>,
WideSparse<3>,
WideSparse<4>,
WideSparse<5>,
)>(entity_count);
let mut query = world.query::<(
&WideSparse<0>,
&WideSparse<1>,
&WideSparse<2>,
&WideSparse<3>,
&WideSparse<4>,
&WideSparse<5>,
)>();
group.bench_function(
format!("{}_entities_sparse_wide", entity_count),
|bencher| {
let mut world = setup_wide::<(
WideSparse<0>,
WideSparse<1>,
WideSparse<2>,
WideSparse<3>,
WideSparse<4>,
WideSparse<5>,
)>(entity_count);
let mut query = world.query::<(
&WideSparse<0>,
&WideSparse<1>,
&WideSparse<2>,
&WideSparse<3>,
&WideSparse<4>,
&WideSparse<5>,
)>();
bencher.iter(|| {
for i in 0..entity_count {
let entity = Entity::from_raw(i);
assert!(query.get(&world, entity).is_ok());
}
});
});
bencher.iter(|| {
for i in 0..entity_count {
let entity = Entity::from_raw(i);
assert!(query.get(&world, entity).is_ok());
}
});
},
);
}
group.finish();
}
fn world_query_iter(criterion: &mut Criterion) {
pub fn world_query_iter(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("world_query_iter");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -226,7 +218,7 @@ fn world_query_iter(criterion: &mut Criterion) {
group.finish();
}
fn world_query_for_each(criterion: &mut Criterion) {
pub fn world_query_for_each(criterion: &mut Criterion) {
let mut group = criterion.benchmark_group("world_query_for_each");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
@ -265,7 +257,49 @@ fn world_query_for_each(criterion: &mut Criterion) {
group.finish();
}
fn query_get_component(criterion: &mut Criterion) {
pub fn query_get_component_simple(criterion: &mut Criterion) {
#[derive(Component)]
struct A(f32);
let mut group = criterion.benchmark_group("query_get_component_simple");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
group.bench_function("unchecked", |bencher| {
let mut world = World::new();
let entity = world.spawn().insert(A(0.0)).id();
let mut query = world.query::<&mut A>();
bencher.iter(|| {
for _x in 0..100000 {
let mut a = unsafe { query.get_unchecked(&mut world, entity).unwrap() };
a.0 += 1.0;
}
});
});
group.bench_function("system", |bencher| {
let mut world = World::new();
let entity = world.spawn().insert(A(0.0)).id();
fn query_system(In(entity): In<Entity>, mut query: Query<&mut A>) {
for _ in 0..100_000 {
let mut a = query.get_mut(entity).unwrap();
a.0 += 1.0;
}
}
let mut system = IntoSystem::into_system(query_system);
system.initialize(&mut world);
system.update_archetype_component_access(&world);
bencher.iter(|| system.run(entity, &mut world));
});
group.finish();
}
pub 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));
@ -320,7 +354,7 @@ fn query_get_component(criterion: &mut Criterion) {
group.finish();
}
fn query_get(criterion: &mut Criterion) {
pub 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));