Basic event benchmarks (#8251)

# Objective
Fix #7731. Add basic Event sending and iteration benchmarks to
bevy_ecs's benchmark suite.

## Solution
Add said benchmarks scaling from 100 to 50,000 events.

Not sure if I want to include a randomization of the events going in,
the current implementation might be too easy for the compiler to
optimize.

---------

Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
This commit is contained in:
James Liu 2023-03-31 00:12:18 -07:00 committed by GitHub
parent a954f3e150
commit 8e82c88131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 110 additions and 1 deletions

View File

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

View File

@ -0,0 +1,22 @@
use bevy_ecs::prelude::*;
pub struct Benchmark<const SIZE: usize>(Events<[u8; SIZE]>);
impl<const SIZE: usize> Benchmark<SIZE> {
pub fn new(count: usize) -> Self {
let mut events = Events::default();
for _ in 0..count {
events.send([0u8; SIZE]);
}
Self(events)
}
pub fn run(&mut self) {
let mut reader = self.0.get_reader();
for evt in reader.iter(&self.0) {
std::hint::black_box(evt);
}
}
}

View File

@ -0,0 +1,56 @@
use criterion::*;
mod iter;
mod send;
criterion_group!(event_benches, send, iter,);
fn send(c: &mut Criterion) {
let mut group = c.benchmark_group("events_send");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
for count in [100, 1000, 10000, 50000] {
group.bench_function(format!("size_4_events_{}", count), |b| {
let mut bench = send::Benchmark::<4>::new(count);
b.iter(move || bench.run());
});
}
for count in [100, 1000, 10000, 50000] {
group.bench_function(format!("size_16_events_{}", count), |b| {
let mut bench = send::Benchmark::<16>::new(count);
b.iter(move || bench.run());
});
}
for count in [100, 1000, 10000, 50000] {
group.bench_function(format!("size_512_events_{}", count), |b| {
let mut bench = send::Benchmark::<512>::new(count);
b.iter(move || bench.run());
});
}
group.finish();
}
fn iter(c: &mut Criterion) {
let mut group = c.benchmark_group("events_iter");
group.warm_up_time(std::time::Duration::from_millis(500));
group.measurement_time(std::time::Duration::from_secs(4));
for count in [100, 1000, 10000, 50000] {
group.bench_function(format!("size_4_events_{}", count), |b| {
let mut bench = iter::Benchmark::<4>::new(count);
b.iter(move || bench.run());
});
}
for count in [100, 1000, 10000, 50000] {
group.bench_function(format!("size_16_events_{}", count), |b| {
let mut bench = iter::Benchmark::<4>::new(count);
b.iter(move || bench.run());
});
}
for count in [100, 1000, 10000, 50000] {
group.bench_function(format!("size_512_events_{}", count), |b| {
let mut bench = iter::Benchmark::<512>::new(count);
b.iter(move || bench.run());
});
}
group.finish();
}

View File

@ -0,0 +1,29 @@
use bevy_ecs::prelude::*;
pub struct Benchmark<const SIZE: usize> {
events: Events<[u8; SIZE]>,
count: usize,
}
impl<const SIZE: usize> Benchmark<SIZE> {
pub fn new(count: usize) -> Self {
let mut events = Events::default();
// Force both internal buffers to be allocated.
for _ in 0..2 {
for _ in 0..count {
events.send([0u8; SIZE]);
}
events.update();
}
Self { events, count }
}
pub fn run(&mut self) {
for _ in 0..self.count {
self.events.send(std::hint::black_box([0u8; SIZE]));
}
self.events.update();
}
}