mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
112 lines
2.8 KiB
Rust
112 lines
2.8 KiB
Rust
|
use criterion::*;
|
||
|
|
||
|
use cgmath::prelude::*;
|
||
|
use cgmath::{vec3, Matrix4, Quaternion, Vector3};
|
||
|
use legion::prelude::*;
|
||
|
use rayon::join;
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct Position(Vector3<f32>);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct Orientation(Quaternion<f32>);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct Scale(Vector3<f32>);
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||
|
struct Transform(Matrix4<f32>);
|
||
|
|
||
|
fn data(n: usize) -> Vec<(Position, Orientation, Scale, Transform)> {
|
||
|
let mut v = Vec::<(Position, Orientation, Scale, Transform)>::new();
|
||
|
|
||
|
for _ in 0..n {
|
||
|
v.push((
|
||
|
Position(vec3(0.0, 0.0, 0.0)),
|
||
|
Orientation(Quaternion::new(1.0, 0.0, 0.0, 0.0)),
|
||
|
Scale(vec3(0.0, 0.0, 0.0)),
|
||
|
Transform(Matrix4::identity()),
|
||
|
));
|
||
|
}
|
||
|
|
||
|
v
|
||
|
}
|
||
|
|
||
|
fn setup(data: Vec<(Position, Orientation, Scale, Transform)>) -> World {
|
||
|
let universe = Universe::new();
|
||
|
let mut world = universe.create_world();
|
||
|
|
||
|
world.insert((), data);
|
||
|
|
||
|
world
|
||
|
}
|
||
|
|
||
|
fn process(
|
||
|
position: &Vector3<f32>,
|
||
|
orientation: &Quaternion<f32>,
|
||
|
scale: &Vector3<f32>,
|
||
|
) -> Matrix4<f32> {
|
||
|
let rot: Matrix4<f32> = (*orientation).into();
|
||
|
Matrix4::from_nonuniform_scale(scale.x, scale.y, scale.z)
|
||
|
* rot
|
||
|
* Matrix4::from_translation(*position)
|
||
|
}
|
||
|
|
||
|
fn ideal(data: &mut Vec<(Position, Orientation, Scale, Transform)>) {
|
||
|
for (pos, orient, scale, trans) in data.iter_mut() {
|
||
|
trans.0 = process(&pos.0, &orient.0, &scale.0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn sequential(world: &mut World) {
|
||
|
for (pos, orient, scale, mut trans) in <(
|
||
|
Read<Position>,
|
||
|
Read<Orientation>,
|
||
|
Read<Scale>,
|
||
|
Write<Transform>,
|
||
|
)>::query()
|
||
|
.iter_mut(world)
|
||
|
{
|
||
|
trans.0 = process(&pos.0, &orient.0, &scale.0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn par_for_each_mut(world: &mut World) {
|
||
|
<(
|
||
|
Read<Position>,
|
||
|
Read<Orientation>,
|
||
|
Read<Scale>,
|
||
|
Write<Transform>,
|
||
|
)>::query()
|
||
|
.par_for_each_mut(world, |(pos, orient, scale, mut trans)| {
|
||
|
trans.0 = process(&pos.0, &orient.0, &scale.0);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
fn bench_transform(c: &mut Criterion) {
|
||
|
c.bench(
|
||
|
"update transform (experimental)",
|
||
|
ParameterizedBenchmark::new(
|
||
|
"ideal sequential",
|
||
|
|b, n| {
|
||
|
let mut data = data(*n);
|
||
|
b.iter(|| ideal(&mut data));
|
||
|
},
|
||
|
(1..11).map(|i| i * 1000),
|
||
|
)
|
||
|
.with_function("sequential", |b, n| {
|
||
|
let data = data(*n);
|
||
|
let mut world = setup(data);
|
||
|
b.iter(|| sequential(&mut world));
|
||
|
})
|
||
|
.with_function("par_for_each_mut", |b, n| {
|
||
|
let data = data(*n);
|
||
|
let mut world = setup(data);
|
||
|
join(|| {}, || b.iter(|| par_for_each_mut(&mut world)));
|
||
|
}),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
criterion_group!(iterate, bench_transform);
|
||
|
criterion_main!(iterate);
|