From e9f9ac1edd9c79cd5e2a2bb6a282999310af92f5 Mon Sep 17 00:00:00 2001 From: Nicola Papale Date: Sat, 13 Jan 2024 16:09:58 +0100 Subject: [PATCH] Inline trivial methods in bevy_hierarchy In #11330 I found out that `Parent::get` didn't get inlined, **even with LTO on**! Not sure what's up with that, but marking functions that consist of a single call as `inline(always)` has no downside. `inline(always)` may increase compilation time proportional to how many time the function is called **and the size of the function marked with `inline`**. Since we mark as `inline` no-ops functions, there is no cost to it. I also took the opportunity to `inline` other functions. I'm not as confident that marking functions calling other functions as `inline` works similarly to very simple functions, so I used `inline` over `inline(always)`. --- crates/bevy_hierarchy/src/components/children.rs | 10 ++++++++++ crates/bevy_hierarchy/src/components/parent.rs | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/crates/bevy_hierarchy/src/components/children.rs b/crates/bevy_hierarchy/src/components/children.rs index 7030d4fdfee6a..57556747fcef5 100644 --- a/crates/bevy_hierarchy/src/components/children.rs +++ b/crates/bevy_hierarchy/src/components/children.rs @@ -41,6 +41,7 @@ impl MapEntities for Children { // However Children should only ever be set with a real user-defined entities. Its worth looking // into better ways to handle cases like this. impl FromWorld for Children { + #[inline] fn from_world(_world: &mut World) -> Self { Children(SmallVec::new()) } @@ -48,11 +49,13 @@ impl FromWorld for Children { impl Children { /// Constructs a [`Children`] component with the given entities. + #[inline] pub(crate) fn from_entities(entities: &[Entity]) -> Self { Self(SmallVec::from_slice(entities)) } /// Swaps the child at `a_index` with the child at `b_index`. + #[inline] pub fn swap(&mut self, a_index: usize, b_index: usize) { self.0.swap(a_index, b_index); } @@ -65,6 +68,7 @@ impl Children { /// For the unstable version, see [`sort_unstable_by`](Children::sort_unstable_by). /// /// See also [`sort_by_key`](Children::sort_by_key), [`sort_by_cached_key`](Children::sort_by_cached_key). + #[inline] pub fn sort_by(&mut self, compare: F) where F: FnMut(&Entity, &Entity) -> std::cmp::Ordering, @@ -80,6 +84,7 @@ impl Children { /// For the unstable version, see [`sort_unstable_by_key`](Children::sort_unstable_by_key). /// /// See also [`sort_by`](Children::sort_by), [`sort_by_cached_key`](Children::sort_by_cached_key). + #[inline] pub fn sort_by_key(&mut self, compare: F) where F: FnMut(&Entity) -> K, @@ -95,6 +100,7 @@ impl Children { /// For the underlying implementation, see [`slice::sort_by_cached_key`]. /// /// See also [`sort_by`](Children::sort_by), [`sort_by_key`](Children::sort_by_key). + #[inline] pub fn sort_by_cached_key(&mut self, compare: F) where F: FnMut(&Entity) -> K, @@ -111,6 +117,7 @@ impl Children { /// For the stable version, see [`sort_by`](Children::sort_by). /// /// See also [`sort_unstable_by_key`](Children::sort_unstable_by_key). + #[inline] pub fn sort_unstable_by(&mut self, compare: F) where F: FnMut(&Entity, &Entity) -> std::cmp::Ordering, @@ -126,6 +133,7 @@ impl Children { /// For the stable version, see [`sort_by_key`](Children::sort_by_key). /// /// See also [`sort_unstable_by`](Children::sort_unstable_by). + #[inline] pub fn sort_unstable_by_key(&mut self, compare: F) where F: FnMut(&Entity) -> K, @@ -138,6 +146,7 @@ impl Children { impl Deref for Children { type Target = [Entity]; + #[inline(always)] fn deref(&self) -> &Self::Target { &self.0[..] } @@ -148,6 +157,7 @@ impl<'a> IntoIterator for &'a Children { type IntoIter = slice::Iter<'a, Entity>; + #[inline(always)] fn into_iter(self) -> Self::IntoIter { self.0.iter() } diff --git a/crates/bevy_hierarchy/src/components/parent.rs b/crates/bevy_hierarchy/src/components/parent.rs index bffd3c28f3646..2ba6a10ccb779 100644 --- a/crates/bevy_hierarchy/src/components/parent.rs +++ b/crates/bevy_hierarchy/src/components/parent.rs @@ -27,6 +27,7 @@ pub struct Parent(pub(crate) Entity); impl Parent { /// Gets the [`Entity`] ID of the parent. + #[inline(always)] pub fn get(&self) -> Entity { self.0 } @@ -37,6 +38,7 @@ impl Parent { /// for both [`Children`] & [`Parent`] that is agnostic to edge direction. /// /// [`Children`]: super::children::Children + #[inline(always)] pub fn as_slice(&self) -> &[Entity] { std::slice::from_ref(&self.0) } @@ -47,6 +49,7 @@ impl Parent { // However Parent should only ever be set with a real user-defined entity. Its worth looking into // better ways to handle cases like this. impl FromWorld for Parent { + #[inline(always)] fn from_world(_world: &mut World) -> Self { Parent(Entity::PLACEHOLDER) } @@ -61,6 +64,7 @@ impl MapEntities for Parent { impl Deref for Parent { type Target = Entity; + #[inline(always)] fn deref(&self) -> &Self::Target { &self.0 }