Skip to content

Commit 6719c2c

Browse files
committed
Extract monomorphic get_insert_bundle_info function (#1910)
This shrinks breakout from 316k to 310k when using `--feature dynamic`. I haven't run the ecs benchmark to test performance as my laptop is too noisy for reliable benchmarking.
1 parent 7c274e5 commit 6719c2c

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

crates/bevy_ecs/src/world/entity_ref.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
archetype::{Archetype, ArchetypeId, Archetypes, ComponentStatus},
33
bundle::{Bundle, BundleInfo},
44
component::{Component, ComponentId, ComponentTicks, Components, StorageType},
5-
entity::{Entity, EntityLocation},
5+
entity::{Entities, Entity, EntityLocation},
66
storage::{SparseSet, Storages},
77
world::{Mut, World},
88
};
@@ -182,7 +182,6 @@ impl<'w> EntityMut<'w> {
182182
})
183183
}
184184

185-
// TODO: factor out non-generic part to cut down on monomorphization (just check perf)
186185
// TODO: move relevant methods to World (add/remove bundle)
187186
pub fn insert_bundle<T: Bundle>(&mut self, bundle: T) -> &mut Self {
188187
let entity = self.entity;
@@ -195,19 +194,28 @@ impl<'w> EntityMut<'w> {
195194
let bundle_info = self.world.bundles.init_info::<T>(components);
196195
let current_location = self.location;
197196

198-
let (archetype, bundle_status, archetype_index) = unsafe {
197+
// Use a non-generic function to cut down on monomorphization
198+
unsafe fn get_insert_bundle_info<'a>(
199+
entities: &mut Entities,
200+
archetypes: &'a mut Archetypes,
201+
components: &mut Components,
202+
storages: &mut Storages,
203+
bundle_info: &BundleInfo,
204+
current_location: EntityLocation,
205+
entity: Entity,
206+
) -> (&'a Archetype, &'a Vec<ComponentStatus>, EntityLocation) {
199207
// SAFE: component ids in `bundle_info` and self.location are valid
200208
let new_archetype_id = add_bundle_to_archetype(
201209
archetypes,
202210
storages,
203211
components,
204-
self.location.archetype_id,
212+
current_location.archetype_id,
205213
bundle_info,
206214
);
207215
if new_archetype_id == current_location.archetype_id {
208216
let archetype = &archetypes[current_location.archetype_id];
209217
let edge = archetype.edges().get_add_bundle(bundle_info.id).unwrap();
210-
(archetype, &edge.bundle_status, current_location.index)
218+
(archetype, &edge.bundle_status, current_location)
211219
} else {
212220
let (old_table_row, old_table_id) = {
213221
let old_archetype = &mut archetypes[current_location.archetype_id];
@@ -241,22 +249,34 @@ impl<'w> EntityMut<'w> {
241249
new_location
242250
};
243251

244-
self.location = new_location;
245-
entities.meta[self.entity.id as usize].location = new_location;
252+
entities.meta[entity.id as usize].location = new_location;
246253
let (old_archetype, new_archetype) =
247254
archetypes.get_2_mut(current_location.archetype_id, new_archetype_id);
248255
let edge = old_archetype
249256
.edges()
250257
.get_add_bundle(bundle_info.id)
251258
.unwrap();
252-
(&*new_archetype, &edge.bundle_status, new_location.index)
259+
(&*new_archetype, &edge.bundle_status, new_location)
253260

254261
// Sparse set components are intentionally ignored here. They don't need to move
255262
}
263+
}
264+
265+
let (archetype, bundle_status, new_location) = unsafe {
266+
get_insert_bundle_info(
267+
entities,
268+
archetypes,
269+
components,
270+
storages,
271+
bundle_info,
272+
current_location,
273+
entity,
274+
)
256275
};
276+
self.location = new_location;
257277

258278
let table = &storages.tables[archetype.table_id()];
259-
let table_row = archetype.entity_table_row(archetype_index);
279+
let table_row = archetype.entity_table_row(new_location.index);
260280
// SAFE: table row is valid
261281
unsafe {
262282
bundle_info.write_components(

0 commit comments

Comments
 (0)