Skip to content

Commit

Permalink
Updated CommandQueue Changes to avoid &mut Option<&mut World> whe…
Browse files Browse the repository at this point in the history
…re possible

Also removed one branch from `apply`.
  • Loading branch information
bushrat011899 committed Nov 26, 2023
1 parent cd4257c commit baa628f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 39 deletions.
49 changes: 25 additions & 24 deletions benches/benches/bevy_utils/entity_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,42 +33,43 @@ fn entity_set_build_and_lookup(c: &mut Criterion) {
for size in SIZES {
// Get some random-but-consistent entities to use for all the benches below.
let mut rng = ChaCha8Rng::seed_from_u64(size as u64);
let entities = Vec::from_iter(
std::iter::repeat_with(|| make_entity(&mut rng, size)).take(size),
);
let entities =
Vec::from_iter(std::iter::repeat_with(|| make_entity(&mut rng, size)).take(size));

group.throughput(Throughput::Elements(size as u64));
group.bench_function(
BenchmarkId::new("entity_set_build", size),
|bencher| {
bencher.iter_with_large_drop(|| EntityHashSet::from_iter(entities.iter().copied()));
},
);
group.bench_function(
BenchmarkId::new("entity_set_lookup_hit", size),
|bencher| {
let set = EntityHashSet::from_iter(entities.iter().copied());
bencher.iter(|| entities.iter().copied().filter(|e| set.contains(e)).count());
},
);
group.bench_function(BenchmarkId::new("entity_set_build", size), |bencher| {
bencher.iter_with_large_drop(|| EntityHashSet::from_iter(entities.iter().copied()));
});
group.bench_function(BenchmarkId::new("entity_set_lookup_hit", size), |bencher| {
let set = EntityHashSet::from_iter(entities.iter().copied());
bencher.iter(|| entities.iter().copied().filter(|e| set.contains(e)).count());
});
group.bench_function(
BenchmarkId::new("entity_set_lookup_miss_id", size),
|bencher| {
let set = EntityHashSet::from_iter(entities.iter().copied());
bencher.iter(|| entities.iter()
.copied()
.map(|e| Entity::from_bits(e.to_bits() + 1))
.filter(|e| set.contains(e)).count());
bencher.iter(|| {
entities
.iter()
.copied()
.map(|e| Entity::from_bits(e.to_bits() + 1))
.filter(|e| set.contains(e))
.count()
});
},
);
group.bench_function(
BenchmarkId::new("entity_set_lookup_miss_gen", size),
|bencher| {
let set = EntityHashSet::from_iter(entities.iter().copied());
bencher.iter(|| entities.iter()
.copied()
.map(|e| Entity::from_bits(e.to_bits() + (1 << 32)))
.filter(|e| set.contains(e)).count());
bencher.iter(|| {
entities
.iter()
.copied()
.map(|e| Entity::from_bits(e.to_bits() + (1 << 32)))
.filter(|e| set.contains(e))
.count()
});
},
);
}
Expand Down
28 changes: 13 additions & 15 deletions crates/bevy_ecs/src/system/commands/command_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl CommandQueue {

let meta = CommandMeta {
consume_command_and_get_size: |command, world| {
// SAFETY: According to the invariants of `CommandMeta.apply_command_and_get_size`,
// SAFETY: According to the invariants of `CommandMeta.consume_command_and_get_size`,
// `command` must point to a value of type `C`.
let command: C = unsafe { command.read_unaligned() };
match world {
Expand Down Expand Up @@ -98,15 +98,20 @@ impl CommandQueue {
}
}

/// Execute or discard the queued [commands](`Command`).
/// Execute the queued [`Command`]s in the world.
/// This clears the queue.
#[inline]
fn apply_maybe_world(&mut self, world: &mut Option<&mut World>) {
pub fn apply(&mut self, world: &mut World) {
// flush the previously queued entities
if let Some(world) = world {
world.flush();
}
world.flush();

self.apply_maybe_world(Some(world));
}

/// Execute or discard the queued [commands](`Command`).
/// This clears the queue.
#[inline]
fn apply_maybe_world(&mut self, mut world: Option<&mut World>) {
// The range of pointers of the filled portion of `self.bytes`.
let bytes_range = self.bytes.as_mut_ptr_range();

Expand Down Expand Up @@ -137,7 +142,7 @@ impl CommandQueue {
// SAFETY: The data underneath the cursor must correspond to the type erased in metadata,
// since they were stored next to each other by `.push()`.
// For ZSTs, the type doesn't matter as long as the pointer is non-null.
let size = unsafe { (meta.consume_command_and_get_size)(cmd, world) };
let size = unsafe { (meta.consume_command_and_get_size)(cmd, &mut world) };
// Advance the cursor past the command. For ZSTs, the cursor will not move.
// At this point, it will either point to the next `CommandMeta`,
// or the cursor will be out of bounds and the loop will end.
Expand All @@ -151,18 +156,11 @@ impl CommandQueue {
pub fn append(&mut self, other: &mut CommandQueue) {
self.bytes.append(&mut other.bytes);
}

/// Execute the queued [`Command`]s in the world.
/// This clears the queue.
#[inline]
pub fn apply(&mut self, world: &mut World) {
self.apply_maybe_world(&mut Some(world));
}
}

impl Drop for CommandQueue {
fn drop(&mut self) {
self.apply_maybe_world(&mut None);
self.apply_maybe_world(None);
}
}

Expand Down

0 comments on commit baa628f

Please sign in to comment.