Overhaul bezier curve benchmarks (#17016)
# Objective - Part of #16647. - The benchmarks for bezier curves have several issues and do not yet use the new `bench!` naming scheme. ## Solution - Make all `bevy_math` benchmarks use the `bench!` macro for their name. - Delete the `build_accel_cubic()` benchmark, since it was an exact duplicate of `build_pos_cubic()`. - Remove `collect::<Vec<_>>()` call in `build_pos_cubic()` and replace it with a `for` loop. - Combine all of the benchmarks that measure `curve.position()` under a single group, `curve_position`, and extract the common bench routine into a helper function. - Move the time calculation for the `curve.ease()` benchmark into the setup closure so it is not tracked. - Rename the benchmarks to be more descriptive on what they do. - `easing_1000` -> `segment_ease` - `cubic_position_Vec2` -> `curve_position/vec2` - `cubic_position_Vec3A` -> `curve_position/vec3a` - `cubic_position_Vec3` -> `curve_position/vec3` - `build_pos_cubic_100_points` -> `curve_iter_positions` ## Testing - `cargo test -p benches --bench math` - `cargo bench -p benches --bench math` - Then open `./target/criterion/report/index.html` to see the report! --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
8c34f00deb
commit
291cb31798
@ -1,63 +1,83 @@
|
||||
use benches::bench;
|
||||
use bevy_math::{prelude::*, VectorSpace};
|
||||
use core::hint::black_box;
|
||||
use criterion::{
|
||||
criterion_group, measurement::Measurement, BatchSize, BenchmarkGroup, BenchmarkId, Criterion,
|
||||
};
|
||||
|
||||
use criterion::{criterion_group, Criterion};
|
||||
criterion_group!(benches, segment_ease, curve_position, curve_iter_positions);
|
||||
|
||||
use bevy_math::prelude::*;
|
||||
fn segment_ease(c: &mut Criterion) {
|
||||
let segment = black_box(CubicSegment::new_bezier(vec2(0.25, 0.1), vec2(0.25, 1.0)));
|
||||
|
||||
fn easing(c: &mut Criterion) {
|
||||
let cubic_bezier = CubicSegment::new_bezier(vec2(0.25, 0.1), vec2(0.25, 1.0));
|
||||
c.bench_function("easing_1000", |b| {
|
||||
b.iter(|| {
|
||||
(0..1000).map(|i| i as f32 / 1000.0).for_each(|t| {
|
||||
black_box(cubic_bezier.ease(black_box(t)));
|
||||
});
|
||||
});
|
||||
c.bench_function(bench!("segment_ease"), |b| {
|
||||
let mut t = 0;
|
||||
|
||||
b.iter_batched(
|
||||
|| {
|
||||
// Increment `t` by 1, but use modulo to constrain it to `0..=1000`.
|
||||
t = (t + 1) % 1001;
|
||||
|
||||
// Return time as a decimal between 0 and 1, inclusive.
|
||||
t as f32 / 1000.0
|
||||
},
|
||||
|t| segment.ease(t),
|
||||
BatchSize::SmallInput,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn cubic_2d(c: &mut Criterion) {
|
||||
let bezier = CubicBezier::new([[
|
||||
fn curve_position(c: &mut Criterion) {
|
||||
/// A helper function that benchmarks calling [`CubicCurve::position()`] over a generic [`VectorSpace`].
|
||||
fn bench_curve<M: Measurement, P: VectorSpace>(
|
||||
group: &mut BenchmarkGroup<M>,
|
||||
name: &str,
|
||||
curve: CubicCurve<P>,
|
||||
) {
|
||||
group.bench_with_input(BenchmarkId::from_parameter(name), &curve, |b, curve| {
|
||||
b.iter(|| curve.position(black_box(0.5)));
|
||||
});
|
||||
}
|
||||
|
||||
let mut group = c.benchmark_group(bench!("curve_position"));
|
||||
|
||||
let bezier_2 = CubicBezier::new([[
|
||||
vec2(0.0, 0.0),
|
||||
vec2(0.0, 1.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(1.0, 1.0),
|
||||
]])
|
||||
.to_curve()
|
||||
.expect("Unable to build a curve from this data");
|
||||
c.bench_function("cubic_position_Vec2", |b| {
|
||||
b.iter(|| black_box(bezier.position(black_box(0.5))));
|
||||
});
|
||||
}
|
||||
.unwrap();
|
||||
|
||||
fn cubic(c: &mut Criterion) {
|
||||
let bezier = CubicBezier::new([[
|
||||
vec3a(0.0, 0.0, 0.0),
|
||||
vec3a(0.0, 1.0, 0.0),
|
||||
vec3a(1.0, 0.0, 0.0),
|
||||
vec3a(1.0, 1.0, 1.0),
|
||||
]])
|
||||
.to_curve()
|
||||
.expect("Unable to build a curve from this data");
|
||||
c.bench_function("cubic_position_Vec3A", |b| {
|
||||
b.iter(|| black_box(bezier.position(black_box(0.5))));
|
||||
});
|
||||
}
|
||||
bench_curve(&mut group, "vec2", bezier_2);
|
||||
|
||||
fn cubic_vec3(c: &mut Criterion) {
|
||||
let bezier = CubicBezier::new([[
|
||||
let bezier_3 = CubicBezier::new([[
|
||||
vec3(0.0, 0.0, 0.0),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
vec3(1.0, 0.0, 0.0),
|
||||
vec3(1.0, 1.0, 1.0),
|
||||
]])
|
||||
.to_curve()
|
||||
.expect("Unable to build a curve from this data");
|
||||
c.bench_function("cubic_position_Vec3", |b| {
|
||||
b.iter(|| black_box(bezier.position(black_box(0.5))));
|
||||
});
|
||||
.unwrap();
|
||||
|
||||
bench_curve(&mut group, "vec3", bezier_3);
|
||||
|
||||
let bezier_3a = CubicBezier::new([[
|
||||
vec3a(0.0, 0.0, 0.0),
|
||||
vec3a(0.0, 1.0, 0.0),
|
||||
vec3a(1.0, 0.0, 0.0),
|
||||
vec3a(1.0, 1.0, 1.0),
|
||||
]])
|
||||
.to_curve()
|
||||
.unwrap();
|
||||
|
||||
bench_curve(&mut group, "vec3a", bezier_3a);
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn build_pos_cubic(c: &mut Criterion) {
|
||||
fn curve_iter_positions(c: &mut Criterion) {
|
||||
let bezier = CubicBezier::new([[
|
||||
vec3a(0.0, 0.0, 0.0),
|
||||
vec3a(0.0, 1.0, 0.0),
|
||||
@ -65,32 +85,15 @@ fn build_pos_cubic(c: &mut Criterion) {
|
||||
vec3a(1.0, 1.0, 1.0),
|
||||
]])
|
||||
.to_curve()
|
||||
.expect("Unable to build a curve from this data");
|
||||
c.bench_function("build_pos_cubic_100_points", |b| {
|
||||
b.iter(|| black_box(bezier.iter_positions(black_box(100)).collect::<Vec<_>>()));
|
||||
.unwrap();
|
||||
|
||||
c.bench_function(bench!("curve_iter_positions"), |b| {
|
||||
b.iter(|| {
|
||||
for x in bezier.iter_positions(black_box(100)) {
|
||||
// Discard `x`, since we just care about `iter_positions()` being consumed, but make
|
||||
// the compiler believe `x` is being used so it doesn't eliminate the iterator.
|
||||
black_box(x);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn build_accel_cubic(c: &mut Criterion) {
|
||||
let bezier = CubicBezier::new([[
|
||||
vec3a(0.0, 0.0, 0.0),
|
||||
vec3a(0.0, 1.0, 0.0),
|
||||
vec3a(1.0, 0.0, 0.0),
|
||||
vec3a(1.0, 1.0, 1.0),
|
||||
]])
|
||||
.to_curve()
|
||||
.expect("Unable to build a curve from this data");
|
||||
c.bench_function("build_accel_cubic_100_points", |b| {
|
||||
b.iter(|| black_box(bezier.iter_positions(black_box(100)).collect::<Vec<_>>()));
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
easing,
|
||||
cubic_2d,
|
||||
cubic_vec3,
|
||||
cubic,
|
||||
build_pos_cubic,
|
||||
build_accel_cubic,
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user