Skip to content

Commit

Permalink
Apply exponential resize strategy to reserve
Browse files Browse the repository at this point in the history
Dramatically improves performance of iterated spawn_batch.
  • Loading branch information
Ralith committed Jul 24, 2021
1 parent b158378 commit a8545a2
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
14 changes: 11 additions & 3 deletions src/archetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ impl Archetype {
/// Every type must be written immediately after this call
pub(crate) unsafe fn allocate(&mut self, id: u32) -> u32 {
if self.len as usize == self.entities.len() {
self.grow(self.len.max(64));
self.grow(64);
}

self.entities[self.len as usize] = id;
Expand All @@ -237,15 +237,23 @@ impl Archetype {

pub(crate) fn reserve(&mut self, additional: u32) {
if additional > (self.capacity() - self.len()) {
self.grow(additional - (self.capacity() - self.len()));
let increment = additional - (self.capacity() - self.len());
self.grow(increment.max(64));
}
}

pub(crate) fn capacity(&self) -> u32 {
self.entities.len() as u32
}

fn grow(&mut self, increment: u32) {
/// Increase capacity by at least `min_increment`
fn grow(&mut self, min_increment: u32) {
// Double capacity or increase it by `min_increment`, whichever is larger.
self.grow_exact(self.capacity().max(min_increment))
}

/// Increase capacity by exactly `increment`
fn grow_exact(&mut self, increment: u32) {
unsafe {
let old_count = self.len as usize;
let new_cap = self.entities.len() + increment as usize;
Expand Down
8 changes: 5 additions & 3 deletions src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ impl ColumnBatchType {
arch.reserve(size);
ColumnBatchBuilder {
fill,
target_fill: size,
archetype: Some(arch),
}
}
Expand All @@ -42,6 +43,7 @@ impl ColumnBatchType {
pub struct ColumnBatchBuilder {
/// Number of components written so far for each component type
fill: TypeIdMap<u32>,
target_fill: u32,
pub(crate) archetype: Option<Archetype>,
}

Expand All @@ -62,7 +64,7 @@ impl ColumnBatchBuilder {
Some(BatchWriter {
fill: self.fill.entry(TypeId::of::<T>()).or_insert(0),
storage: unsafe {
slice::from_raw_parts_mut(base.as_ptr().cast(), archetype.capacity() as usize)
slice::from_raw_parts_mut(base.as_ptr().cast(), self.target_fill as usize)
.iter_mut()
},
})
Expand All @@ -74,12 +76,12 @@ impl ColumnBatchBuilder {
if archetype
.types()
.iter()
.any(|ty| self.fill.get(&ty.id()).copied().unwrap_or(0) != archetype.capacity())
.any(|ty| self.fill.get(&ty.id()).copied().unwrap_or(0) != self.target_fill)
{
return Err(BatchIncomplete { _opaque: () });
}
unsafe {
archetype.set_len(archetype.capacity());
archetype.set_len(self.target_fill);
}
Ok(ColumnBatch(archetype))
}
Expand Down
2 changes: 1 addition & 1 deletion src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ impl World {
Ok(())
}

/// Ensure `additional` entities with exact components `T` can be spawned without reallocating
/// Ensure at least `additional` entities with exact components `T` can be spawned without reallocating
pub fn reserve<T: Bundle + 'static>(&mut self, additional: u32) {
self.reserve_inner::<T>(additional);
}
Expand Down

0 comments on commit a8545a2

Please sign in to comment.