Fix regression on the get/get_mut/get_not_found (#19505)

# Objective

- Partial fix #19504
- As more features were added to Bevy ECS, certain core hot-path
function calls exceeded LLVM's automatic inlining threshold, leading to
significant performance regressions in some cases.



## Solution

- inline more functions.


## Performance
This brought nearly 3x improvement in Windows bench (using Sander's
testing code)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
re0312 2025-06-07 05:04:27 +08:00 committed by GitHub
parent 8ad7118443
commit 5df9c53977
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 0 deletions

View File

@ -200,6 +200,7 @@ unsafe impl WorldEntityFetch for Entity {
type Mut<'w> = EntityWorldMut<'w>;
type DeferredMut<'w> = EntityMut<'w>;
#[inline]
unsafe fn fetch_ref(
self,
cell: UnsafeWorldCell<'_>,
@ -209,6 +210,7 @@ unsafe impl WorldEntityFetch for Entity {
Ok(unsafe { EntityRef::new(ecell) })
}
#[inline]
unsafe fn fetch_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -223,6 +225,7 @@ unsafe impl WorldEntityFetch for Entity {
Ok(unsafe { EntityWorldMut::new(world, self, Some(location)) })
}
#[inline]
unsafe fn fetch_deferred_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -242,6 +245,7 @@ unsafe impl<const N: usize> WorldEntityFetch for [Entity; N] {
type Mut<'w> = [EntityMut<'w>; N];
type DeferredMut<'w> = [EntityMut<'w>; N];
#[inline]
unsafe fn fetch_ref(
self,
cell: UnsafeWorldCell<'_>,
@ -249,6 +253,7 @@ unsafe impl<const N: usize> WorldEntityFetch for [Entity; N] {
<&Self>::fetch_ref(&self, cell)
}
#[inline]
unsafe fn fetch_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -256,6 +261,7 @@ unsafe impl<const N: usize> WorldEntityFetch for [Entity; N] {
<&Self>::fetch_mut(&self, cell)
}
#[inline]
unsafe fn fetch_deferred_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -273,6 +279,7 @@ unsafe impl<const N: usize> WorldEntityFetch for &'_ [Entity; N] {
type Mut<'w> = [EntityMut<'w>; N];
type DeferredMut<'w> = [EntityMut<'w>; N];
#[inline]
unsafe fn fetch_ref(
self,
cell: UnsafeWorldCell<'_>,
@ -290,6 +297,7 @@ unsafe impl<const N: usize> WorldEntityFetch for &'_ [Entity; N] {
Ok(refs)
}
#[inline]
unsafe fn fetch_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -316,6 +324,7 @@ unsafe impl<const N: usize> WorldEntityFetch for &'_ [Entity; N] {
Ok(refs)
}
#[inline]
unsafe fn fetch_deferred_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -335,6 +344,7 @@ unsafe impl WorldEntityFetch for &'_ [Entity] {
type Mut<'w> = Vec<EntityMut<'w>>;
type DeferredMut<'w> = Vec<EntityMut<'w>>;
#[inline]
unsafe fn fetch_ref(
self,
cell: UnsafeWorldCell<'_>,
@ -349,6 +359,7 @@ unsafe impl WorldEntityFetch for &'_ [Entity] {
Ok(refs)
}
#[inline]
unsafe fn fetch_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -372,6 +383,7 @@ unsafe impl WorldEntityFetch for &'_ [Entity] {
Ok(refs)
}
#[inline]
unsafe fn fetch_deferred_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -391,6 +403,7 @@ unsafe impl WorldEntityFetch for &'_ EntityHashSet {
type Mut<'w> = EntityHashMap<EntityMut<'w>>;
type DeferredMut<'w> = EntityHashMap<EntityMut<'w>>;
#[inline]
unsafe fn fetch_ref(
self,
cell: UnsafeWorldCell<'_>,
@ -404,6 +417,7 @@ unsafe impl WorldEntityFetch for &'_ EntityHashSet {
Ok(refs)
}
#[inline]
unsafe fn fetch_mut(
self,
cell: UnsafeWorldCell<'_>,
@ -417,6 +431,7 @@ unsafe impl WorldEntityFetch for &'_ EntityHashSet {
Ok(refs)
}
#[inline]
unsafe fn fetch_deferred_mut(
self,
cell: UnsafeWorldCell<'_>,

View File

@ -457,6 +457,7 @@ impl<'w> EntityMut<'w> {
/// - `cell` must have permission to mutate every component of the entity.
/// - No accesses to any of the entity's components may exist
/// at the same time as the returned [`EntityMut`].
#[inline]
pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {
Self { cell }
}
@ -1010,6 +1011,7 @@ impl<'w> From<EntityWorldMut<'w>> for EntityMut<'w> {
}
impl<'a> From<&'a mut EntityWorldMut<'_>> for EntityMut<'a> {
#[inline]
fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {
// SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.
unsafe { EntityMut::new(entity.as_unsafe_entity_cell()) }
@ -1122,6 +1124,7 @@ impl<'w> EntityWorldMut<'w> {
}
}
#[inline(always)]
fn as_unsafe_entity_cell_readonly(&self) -> UnsafeEntityCell<'_> {
let location = self.location();
let last_change_tick = self.world.last_change_tick;
@ -1134,6 +1137,8 @@ impl<'w> EntityWorldMut<'w> {
change_tick,
)
}
#[inline(always)]
fn as_unsafe_entity_cell(&mut self) -> UnsafeEntityCell<'_> {
let location = self.location();
let last_change_tick = self.world.last_change_tick;
@ -1146,6 +1151,8 @@ impl<'w> EntityWorldMut<'w> {
change_tick,
)
}
#[inline(always)]
fn into_unsafe_entity_cell(self) -> UnsafeEntityCell<'w> {
let location = self.location();
let last_change_tick = self.world.last_change_tick;
@ -1188,6 +1195,7 @@ impl<'w> EntityWorldMut<'w> {
}
/// Gets read-only access to all of the entity's components.
#[inline]
pub fn as_readonly(&self) -> EntityRef<'_> {
EntityRef::from(self)
}
@ -1199,6 +1207,7 @@ impl<'w> EntityWorldMut<'w> {
}
/// Gets non-structural mutable access to all of the entity's components.
#[inline]
pub fn as_mutable(&mut self) -> EntityMut<'_> {
EntityMut::from(self)
}