This reverts commit08ef2f0a28. # Objective - #4225 was merged without considering the licensing considerations. - It merges in code taken from https://github.com/cart/ecs_bench_suite/tree/bevy-benches/src/bevy. - We can safely assume that we do have a license to cart's contributions. However, these build upon377e96e69a, for which we have no license. - This has been verified by looking in the Cargo.toml, the root folder and the readme, none of which mention a license. Additionally, the string "license" [doesn't appear](https://github.com/rust-gamedev/ecs_bench_suite/search?q=license) in the repository. - This means the code is all rights reserved. - (The author of these commits also hasn't commented in #2373, though even if they had, it would be legally *dubious* to rely on that to license any code they ever wrote) - (Note that the latest commit on the head at https://github.com/rust-gamedev/ecs_bench_suite hasn't had a license added either.) - We are currently incorrectly claiming to be able to give an MIT/Apache 2.0 license to this code. ## Solution - Revert it
This commit is contained in:
parent
08ef2f0a28
commit
95d3f32b9b
@ -7,16 +7,10 @@ publish = false
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
glam = "0.20"
|
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
bevy_ecs = { path = "../crates/bevy_ecs" }
|
bevy_ecs = { path = "../crates/bevy_ecs" }
|
||||||
bevy_tasks = { path = "../crates/bevy_tasks" }
|
bevy_tasks = { path = "../crates/bevy_tasks" }
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "ecs_bench_suite"
|
|
||||||
path = "benches/bevy_ecs/ecs_bench_suite/mod.rs"
|
|
||||||
harness = false
|
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "system_stage"
|
name = "system_stage"
|
||||||
path = "benches/bevy_ecs/stages.rs"
|
path = "benches/bevy_ecs/stages.rs"
|
||||||
|
|||||||
@ -1,30 +0,0 @@
|
|||||||
use bevy::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
struct A(f32);
|
|
||||||
#[derive(Component)]
|
|
||||||
struct B(f32);
|
|
||||||
|
|
||||||
pub struct Benchmark(World, Vec<Entity>);
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut world = World::default();
|
|
||||||
|
|
||||||
let entities = world
|
|
||||||
.spawn_batch((0..10000).map(|_| (A(0.0),)))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
Self(world, entities)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0.insert_one(*entity, B(0.0)).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0.remove_one::<B>(*entity).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct A(Mat4);
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct B(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct C(Mat4);
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct D(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct E(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
#[component(storage = "SparseSet")]
|
|
||||||
struct F(Mat4);
|
|
||||||
pub struct Benchmark(World, Vec<Entity>);
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut world = World::default();
|
|
||||||
let mut entities = Vec::with_capacity(10_000);
|
|
||||||
for _ in 0..10_000 {
|
|
||||||
entities.push(
|
|
||||||
world
|
|
||||||
.spawn()
|
|
||||||
.insert_bundle((
|
|
||||||
A(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
B(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
C(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
D(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
E(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
))
|
|
||||||
.id(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self(world, entities)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0
|
|
||||||
.entity_mut(*entity)
|
|
||||||
.insert(F(Mat4::from_scale(Vec3::ONE)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0.entity_mut(*entity).remove::<F>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct A(Mat4);
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct B(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct C(Mat4);
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct D(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct E(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct F(Mat4);
|
|
||||||
pub struct Benchmark(World, Vec<Entity>);
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut world = World::default();
|
|
||||||
let mut entities = Vec::with_capacity(10_000);
|
|
||||||
for _ in 0..10_000 {
|
|
||||||
entities.push(
|
|
||||||
world
|
|
||||||
.spawn()
|
|
||||||
.insert_bundle((
|
|
||||||
A(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
B(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
C(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
D(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
E(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
))
|
|
||||||
.id(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self(world, entities)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0
|
|
||||||
.entity_mut(*entity)
|
|
||||||
.insert(F(Mat4::from_scale(Vec3::ONE)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0.entity_mut(*entity).remove::<F>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
struct A(f32);
|
|
||||||
#[derive(Component)]
|
|
||||||
#[component(storage = "SparseSet")]
|
|
||||||
struct B(f32);
|
|
||||||
|
|
||||||
pub struct Benchmark(World, Vec<Entity>);
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut world = World::default();
|
|
||||||
let mut entities = Vec::with_capacity(10_000);
|
|
||||||
for _ in 0..10_000 {
|
|
||||||
entities.push(world.spawn().insert(A(0.0)).id());
|
|
||||||
}
|
|
||||||
|
|
||||||
Self(world, entities)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0.entity_mut(*entity).insert(B(0.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0.entity_mut(*entity).remove::<B>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
struct A(f32);
|
|
||||||
#[derive(Component)]
|
|
||||||
struct B(f32);
|
|
||||||
|
|
||||||
pub struct Benchmark(World, Vec<Entity>);
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut world = World::default();
|
|
||||||
let mut entities = Vec::with_capacity(10_000);
|
|
||||||
for _ in 0..10_000 {
|
|
||||||
entities.push(world.spawn().insert(A(0.0)).id());
|
|
||||||
}
|
|
||||||
|
|
||||||
Self(world, entities)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0.entity_mut(*entity).insert(B(0.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
for entity in &self.1 {
|
|
||||||
self.0.entity_mut(*entity).remove::<B>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
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(1.0)));
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
struct Data(f32);
|
|
||||||
|
|
||||||
pub struct Benchmark<'w>(World, QueryState<&'w mut Data>);
|
|
||||||
|
|
||||||
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::<&mut Data>();
|
|
||||||
Self(world, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for mut data in self.1.iter_mut(&mut self.0) {
|
|
||||||
data.0 *= 2.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
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(1.0)));
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
struct Data(f32);
|
|
||||||
|
|
||||||
pub struct Benchmark<'w>(World, QueryState<&'w mut Data>);
|
|
||||||
|
|
||||||
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::<&mut Data>();
|
|
||||||
Self(world, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
self.1.for_each_mut(&mut self.0, |mut data| {
|
|
||||||
data.0 *= 2.0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +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);
|
|
||||||
for archetype in world.archetypes().iter() {
|
|
||||||
system.new_archetype(archetype);
|
|
||||||
}
|
|
||||||
Self(world, entity, Box::new(system))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
self.2.run(self.1, &mut self.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use bevy_tasks::TaskPool;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Position(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Rotation(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Velocity(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Transform(Mat4);
|
|
||||||
|
|
||||||
pub struct Benchmark(World, Box<dyn System<In = (), Out = ()>>);
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut world = World::default();
|
|
||||||
|
|
||||||
world.spawn_batch((0..1000).map(|_| {
|
|
||||||
(
|
|
||||||
Transform(Mat4::from_axis_angle(Vec3::X, 1.2)),
|
|
||||||
Position(Vec3::X),
|
|
||||||
Rotation(Vec3::X),
|
|
||||||
Velocity(Vec3::X),
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
|
|
||||||
fn sys(task_pool: Res<TaskPool>, mut query: Query<(&mut Position, &mut Transform)>) {
|
|
||||||
query.par_for_each_mut(&task_pool, 128, |(mut pos, mut mat)| {
|
|
||||||
for _ in 0..100 {
|
|
||||||
mat.0 = mat.0.inverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.0 = mat.0.transform_vector3(pos.0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
world.insert_resource(TaskPool::default());
|
|
||||||
let mut system = IntoSystem::into_system(sys);
|
|
||||||
system.initialize(&mut world);
|
|
||||||
for archetype in world.archetypes().iter() {
|
|
||||||
system.new_archetype(archetype);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self(world, Box::new(system))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
self.1.run((), &mut self.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,174 +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_foreach;
|
|
||||||
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_foreach;
|
|
||||||
mod simple_iter_sparse;
|
|
||||||
mod simple_iter_sparse_foreach;
|
|
||||||
mod simple_iter_system;
|
|
||||||
mod sparse_frag_iter;
|
|
||||||
mod sparse_frag_iter_foreach;
|
|
||||||
|
|
||||||
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("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("foreach", |b| {
|
|
||||||
let mut bench = simple_iter_foreach::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.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("foreach", |b| {
|
|
||||||
let mut bench = frag_iter_foreach::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("foreach", |b| {
|
|
||||||
let mut bench = sparse_frag_iter_foreach::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);
|
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Transform(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Position(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Rotation(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Velocity(Vec3);
|
|
||||||
|
|
||||||
pub struct Benchmark;
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
let mut world = World::new();
|
|
||||||
world.spawn_batch((0..10_000).map(|_| {
|
|
||||||
(
|
|
||||||
Transform(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
Position(Vec3::X),
|
|
||||||
Rotation(Vec3::X),
|
|
||||||
Velocity(Vec3::X),
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Transform(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Position(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Rotation(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Velocity(Vec3);
|
|
||||||
|
|
||||||
pub struct Benchmark;
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
let mut world = World::new();
|
|
||||||
for _ in 0..10_000 {
|
|
||||||
world.spawn().insert_bundle((
|
|
||||||
Transform(Mat4::from_scale(Vec3::ONE)),
|
|
||||||
Position(Vec3::X),
|
|
||||||
Rotation(Vec3::X),
|
|
||||||
Velocity(Vec3::X),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Transform(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Position(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Rotation(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Velocity(Vec3);
|
|
||||||
|
|
||||||
pub struct Benchmark<'w>(World, QueryState<(&'w Velocity, &'w mut Position)>);
|
|
||||||
|
|
||||||
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)),
|
|
||||||
Position(Vec3::X),
|
|
||||||
Rotation(Vec3::X),
|
|
||||||
Velocity(Vec3::X),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let query = world.query::<(&Velocity, &mut Position)>();
|
|
||||||
Self(world, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for (velocity, mut position) in self.1.iter_mut(&mut self.0) {
|
|
||||||
position.0 += velocity.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Transform(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Position(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Rotation(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Velocity(Vec3);
|
|
||||||
|
|
||||||
pub struct Benchmark<'w>(World, QueryState<(&'w Velocity, &'w mut Position)>);
|
|
||||||
|
|
||||||
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)),
|
|
||||||
Position(Vec3::X),
|
|
||||||
Rotation(Vec3::X),
|
|
||||||
Velocity(Vec3::X),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let query = world.query::<(&Velocity, &mut Position)>();
|
|
||||||
Self(world, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
self.1
|
|
||||||
.for_each_mut(&mut self.0, |(velocity, mut position)| {
|
|
||||||
position.0 += velocity.0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Transform(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
#[component(storage = "SparseSet")]
|
|
||||||
struct Position(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Rotation(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
#[component(storage = "SparseSet")]
|
|
||||||
struct Velocity(Vec3);
|
|
||||||
|
|
||||||
pub struct Benchmark<'w>(World, QueryState<(&'w Velocity, &'w mut Position)>);
|
|
||||||
|
|
||||||
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)),
|
|
||||||
Position(Vec3::X),
|
|
||||||
Rotation(Vec3::X),
|
|
||||||
Velocity(Vec3::X),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let query = world.query::<(&Velocity, &mut Position)>();
|
|
||||||
Self(world, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for (velocity, mut position) in self.1.iter_mut(&mut self.0) {
|
|
||||||
position.0 += velocity.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Transform(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
#[component(storage = "SparseSet")]
|
|
||||||
struct Position(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Rotation(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
#[component(storage = "SparseSet")]
|
|
||||||
struct Velocity(Vec3);
|
|
||||||
|
|
||||||
pub struct Benchmark<'w>(World, QueryState<(&'w Velocity, &'w mut Position)>);
|
|
||||||
|
|
||||||
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)),
|
|
||||||
Position(Vec3::X),
|
|
||||||
Rotation(Vec3::X),
|
|
||||||
Velocity(Vec3::X),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let query = world.query::<(&Velocity, &mut Position)>();
|
|
||||||
Self(world, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
self.1
|
|
||||||
.for_each_mut(&mut self.0, |(velocity, mut position)| {
|
|
||||||
position.0 += velocity.0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
use glam::*;
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Transform(Mat4);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Position(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Rotation(Vec3);
|
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone)]
|
|
||||||
struct Velocity(Vec3);
|
|
||||||
|
|
||||||
pub struct Benchmark(World, Box<dyn System<In = (), Out = ()>>);
|
|
||||||
|
|
||||||
impl Benchmark {
|
|
||||||
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)),
|
|
||||||
Position(Vec3::X),
|
|
||||||
Rotation(Vec3::X),
|
|
||||||
Velocity(Vec3::X),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn query_system(mut query: Query<(&Velocity, &mut Position)>) {
|
|
||||||
for (velocity, mut position) in query.iter_mut() {
|
|
||||||
position.0 += velocity.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut system = IntoSystem::into_system(query_system);
|
|
||||||
system.initialize(&mut world);
|
|
||||||
for archetype in world.archetypes().iter() {
|
|
||||||
system.new_archetype(archetype);
|
|
||||||
}
|
|
||||||
Self(world, Box::new(system))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
self.1.run((), &mut self.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
|
|
||||||
macro_rules! create_entities {
|
|
||||||
($world:ident; $( $variants:ident ),*) => {
|
|
||||||
$(
|
|
||||||
#[derive(Component)]
|
|
||||||
struct $variants(f32);
|
|
||||||
for _ in 0..5 {
|
|
||||||
$world.spawn().insert($variants(0.0));
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#[derive(Component)]
|
|
||||||
struct Data(f32);
|
|
||||||
|
|
||||||
pub struct Benchmark<'w>(World, QueryState<&'w mut Data>);
|
|
||||||
|
|
||||||
impl<'w> Benchmark<'w> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut world = World::new();
|
|
||||||
|
|
||||||
for _ in 0..5 {
|
|
||||||
world.spawn().insert(Data(1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
create_entities!(world; C00, C01, C02, C03, C04, C05, C06, C07, C08, C09);
|
|
||||||
create_entities!(world; C10, C11, C12, C13, C14, C15, C16, C17, C18, C19);
|
|
||||||
create_entities!(world; C20, C21, C22, C23, C24, C25, C26, C27, C28, C29);
|
|
||||||
create_entities!(world; C30, C31, C32, C33, C34, C35, C36, C37, C38, C39);
|
|
||||||
create_entities!(world; C40, C41, C42, C43, C44, C45, C46, C47, C48, C49);
|
|
||||||
create_entities!(world; C50, C51, C52, C53, C54, C55, C56, C57, C58, C59);
|
|
||||||
create_entities!(world; C60, C61, C62, C63, C64, C65, C66, C67, C68, C69);
|
|
||||||
create_entities!(world; C70, C71, C72, C73, C74, C75, C76, C77, C78, C79);
|
|
||||||
create_entities!(world; C80, C81, C82, C83, C84, C85, C86, C87, C88, C89);
|
|
||||||
create_entities!(world; C90, C91, C92, C93, C94, C95, C96, C97, C98, C99);
|
|
||||||
let query = world.query::<&mut Data>();
|
|
||||||
Self(world, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
for mut data in self.1.iter_mut(&mut self.0) {
|
|
||||||
data.0 *= 2.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
use bevy_ecs::prelude::*;
|
|
||||||
|
|
||||||
macro_rules! create_entities {
|
|
||||||
($world:ident; $( $variants:ident ),*) => {
|
|
||||||
$(
|
|
||||||
#[derive(Component)]
|
|
||||||
struct $variants(f32);
|
|
||||||
for _ in 0..5 {
|
|
||||||
$world.spawn().insert($variants(0.0));
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
struct Data(f32);
|
|
||||||
|
|
||||||
pub struct Benchmark<'w>(World, QueryState<&'w mut Data>);
|
|
||||||
|
|
||||||
impl<'w> Benchmark<'w> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let mut world = World::new();
|
|
||||||
for _ in 0..5 {
|
|
||||||
world.spawn().insert(Data(1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
create_entities!(world; C00, C01, C02, C03, C04, C05, C06, C07, C08, C09);
|
|
||||||
create_entities!(world; C10, C11, C12, C13, C14, C15, C16, C17, C18, C19);
|
|
||||||
create_entities!(world; C20, C21, C22, C23, C24, C25, C26, C27, C28, C29);
|
|
||||||
create_entities!(world; C30, C31, C32, C33, C34, C35, C36, C37, C38, C39);
|
|
||||||
create_entities!(world; C40, C41, C42, C43, C44, C45, C46, C47, C48, C49);
|
|
||||||
create_entities!(world; C50, C51, C52, C53, C54, C55, C56, C57, C58, C59);
|
|
||||||
create_entities!(world; C60, C61, C62, C63, C64, C65, C66, C67, C68, C69);
|
|
||||||
create_entities!(world; C70, C71, C72, C73, C74, C75, C76, C77, C78, C79);
|
|
||||||
create_entities!(world; C80, C81, C82, C83, C84, C85, C86, C87, C88, C89);
|
|
||||||
create_entities!(world; C90, C91, C92, C93, C94, C95, C96, C97, C98, C99);
|
|
||||||
let query = world.query::<&mut Data>();
|
|
||||||
Self(world, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
self.1.for_each_mut(&mut self.0, |mut data| {
|
|
||||||
data.0 *= 2.0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user