-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query by Indexed Component Value #17608
base: main
Are you sure you want to change the base?
Changes from 54 commits
001b227
44408ba
df42b47
8f6069a
9c66cd2
5b10abb
ef82a3d
e372f5d
908fd04
88c9b3b
6fbc6c3
14e189e
44c2a3d
1778616
175c6dc
272c979
3f0c733
6b2fe6e
1d502e0
b18de48
beed9bb
a5e189b
ec64913
9171430
c5dac6f
776e0da
ea98ec8
4e5a6e0
4e4e190
6b03687
bdfd4ab
afa0441
4b158a0
e758a62
4d8f503
69ab442
b362d2d
32884e1
2266934
5a1428b
e2508dc
64df47a
5d67b38
7352492
94567fc
a5b1df2
de65088
b1a322d
a024de0
8a28afb
400412f
d886a82
adf1132
5d6606e
afb3ad2
a003f40
7e6c1f9
beecc59
8c2538e
2f64169
8f92f3b
a5160a4
4264e90
62f5fdb
733fdd3
514aadf
c54bec9
70dd03a
21f6b40
cfcb2ae
d7fe564
37dfdaa
6eed8b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
use bevy_ecs::{prelude::*, system::SystemId}; | ||
use core::hint::black_box; | ||
use glam::*; | ||
|
||
const PLANETS: u16 = 1_000; | ||
const SPAWNS: usize = 1_000_000; | ||
|
||
#[derive(Component, Copy, Clone, PartialEq, Eq, Hash)] | ||
#[component(immutable)] | ||
struct Planet(u16); | ||
|
||
fn find_planet_zeroes_indexed(query: QueryByIndex<Planet, &Planet>) { | ||
let mut query = query.at(&Planet(0)); | ||
for planet in query.query().iter() { | ||
let _ = black_box(planet); | ||
} | ||
} | ||
|
||
pub struct Benchmark(World, SystemId); | ||
|
||
impl Benchmark { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
world.add_index::<Planet>(); | ||
|
||
world.spawn_batch((0..PLANETS).map(Planet).cycle().take(SPAWNS)); | ||
|
||
let id = world.register_system(find_planet_zeroes_indexed); | ||
|
||
Self(world, id) | ||
} | ||
|
||
#[inline(never)] | ||
pub fn run(&mut self) { | ||
let _ = self.0.run_system(self.1); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use bevy_ecs::{prelude::*, system::SystemId}; | ||
use core::hint::black_box; | ||
use glam::*; | ||
|
||
const PLANETS: u16 = 1_000; | ||
const SPAWNS: usize = 1_000_000; | ||
|
||
#[derive(Component, Copy, Clone, PartialEq, Eq, Hash)] | ||
#[component(immutable)] | ||
struct Planet(u16); | ||
|
||
fn find_planet_zeroes_naive(query: Query<&Planet>) { | ||
for planet in query.iter().filter(|&&planet| planet == Planet(0)) { | ||
let _ = black_box(planet); | ||
} | ||
} | ||
|
||
pub struct Benchmark(World, SystemId); | ||
|
||
impl Benchmark { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
world.spawn_batch((0..PLANETS).map(Planet).cycle().take(SPAWNS)); | ||
|
||
let id = world.register_system(find_planet_zeroes_naive); | ||
|
||
Self(world, id) | ||
} | ||
|
||
#[inline(never)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you choose to add |
||
pub fn run(&mut self) { | ||
let _ = self.0.run_system(self.1); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use bevy_ecs::{prelude::*, system::SystemId}; | ||
use glam::*; | ||
|
||
const PLANETS: u8 = 16; | ||
const SPAWNS: usize = 10_000; | ||
|
||
#[derive(Component, Copy, Clone, PartialEq, Eq, Hash)] | ||
#[component(immutable)] | ||
struct Planet(u8); | ||
|
||
fn increment_planet_zeroes_indexed( | ||
query: QueryByIndex<Planet, (Entity, &Planet)>, | ||
mut local: Local<u8>, | ||
mut commands: Commands, | ||
) { | ||
let target = Planet(*local); | ||
let next_planet = Planet(target.0 + 1); | ||
|
||
let mut query = query.at(&target); | ||
for (entity, _planet) in query.query().iter() { | ||
commands.entity(entity).insert(next_planet); | ||
} | ||
|
||
*local += 1; | ||
} | ||
|
||
pub struct Benchmark(World, SystemId); | ||
|
||
impl Benchmark { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
world.add_index::<Planet>(); | ||
|
||
world.spawn_batch((0..PLANETS).map(Planet).cycle().take(SPAWNS)); | ||
|
||
let id = world.register_system(increment_planet_zeroes_indexed); | ||
|
||
Self(world, id) | ||
} | ||
|
||
#[inline(never)] | ||
pub fn run(&mut self) { | ||
let _ = self.0.run_system(self.1); | ||
self.0.flush(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use bevy_ecs::{prelude::*, system::SystemId}; | ||
use glam::*; | ||
|
||
const PLANETS: u8 = 16; | ||
const SPAWNS: usize = 10_000; | ||
|
||
#[derive(Component, Copy, Clone, PartialEq, Eq, Hash)] | ||
#[component(immutable)] | ||
struct Planet(u8); | ||
|
||
fn increment_planet_zeroes_naive( | ||
query: Query<(Entity, &Planet)>, | ||
mut local: Local<u8>, | ||
mut commands: Commands, | ||
) { | ||
let target = Planet(*local); | ||
let next_planet = Planet(target.0 + 1); | ||
|
||
for (entity, _planet) in query.iter().filter(|(_, planet)| **planet == target) { | ||
commands.entity(entity).insert(next_planet); | ||
} | ||
|
||
*local += 1; | ||
} | ||
|
||
pub struct Benchmark(World, SystemId); | ||
|
||
impl Benchmark { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
world.spawn_batch((0..PLANETS).map(Planet).cycle().take(SPAWNS)); | ||
|
||
let id = world.register_system(increment_planet_zeroes_naive); | ||
|
||
Self(world, id) | ||
} | ||
|
||
#[inline(never)] | ||
pub fn run(&mut self) { | ||
let _ = self.0.run_system(self.1); | ||
self.0.flush(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
mod index_iter_indexed; | ||
mod index_iter_naive; | ||
mod index_update_indexed; | ||
mod index_update_naive; | ||
|
||
use criterion::{criterion_group, Criterion}; | ||
|
||
criterion_group!(benches, index_iter, index_update,); | ||
|
||
fn index_iter(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("index_iter"); | ||
group.warm_up_time(core::time::Duration::from_millis(500)); | ||
group.measurement_time(core::time::Duration::from_secs(4)); | ||
Comment on lines
+12
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a specific reason you chose these times, which are smaller than the default? |
||
group.bench_function("naive", |b| { | ||
let mut bench = index_iter_naive::Benchmark::new(); | ||
b.iter(move || bench.run()); | ||
}); | ||
group.bench_function("indexed", |b| { | ||
let mut bench = index_iter_indexed::Benchmark::new(); | ||
b.iter(move || bench.run()); | ||
}); | ||
group.finish(); | ||
} | ||
|
||
fn index_update(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("index_update"); | ||
group.warm_up_time(core::time::Duration::from_millis(500)); | ||
group.measurement_time(core::time::Duration::from_secs(4)); | ||
group.bench_function("naive", |b| { | ||
let mut bench = index_update_naive::Benchmark::new(); | ||
b.iter(move || bench.run()); | ||
}); | ||
group.bench_function("indexed", |b| { | ||
let mut bench = index_update_indexed::Benchmark::new(); | ||
b.iter(move || bench.run()); | ||
}); | ||
group.finish(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Nit) The
let _ =
isn't necessary, sinceblack_box()
forces the expression it is passed to be evaluated.black_box()
- How to use this