Inline trivial methods in bevy_hierarchy (#11332)
# Objective In #11330 I found out that `Parent::get` didn't get inlined, **even with LTO on**! This means that just to access a field, we have an instruction cache invalidation, we will move some registers to the stack, will jump to new instructions, move the field into a register, then do the same dance in the other direction to go back to the call site. ## Solution Mark trivial functions as `#[inline]`. `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` functions that consists in a single instruction, the cost is absolutely negligible. 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)`, which doesn't have the same downsides as `inline(always)`. More information on inlining in rust: https://nnethercote.github.io/perf-book/inlining.html
This commit is contained in:
parent
78b5f323f8
commit
a634075a39
@ -41,6 +41,7 @@ impl MapEntities for Children {
|
|||||||
// However Children should only ever be set with a real user-defined entities. Its worth looking
|
// However Children should only ever be set with a real user-defined entities. Its worth looking
|
||||||
// into better ways to handle cases like this.
|
// into better ways to handle cases like this.
|
||||||
impl FromWorld for Children {
|
impl FromWorld for Children {
|
||||||
|
#[inline]
|
||||||
fn from_world(_world: &mut World) -> Self {
|
fn from_world(_world: &mut World) -> Self {
|
||||||
Children(SmallVec::new())
|
Children(SmallVec::new())
|
||||||
}
|
}
|
||||||
@ -48,11 +49,13 @@ impl FromWorld for Children {
|
|||||||
|
|
||||||
impl Children {
|
impl Children {
|
||||||
/// Constructs a [`Children`] component with the given entities.
|
/// Constructs a [`Children`] component with the given entities.
|
||||||
|
#[inline]
|
||||||
pub(crate) fn from_entities(entities: &[Entity]) -> Self {
|
pub(crate) fn from_entities(entities: &[Entity]) -> Self {
|
||||||
Self(SmallVec::from_slice(entities))
|
Self(SmallVec::from_slice(entities))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swaps the child at `a_index` with the child at `b_index`.
|
/// Swaps the child at `a_index` with the child at `b_index`.
|
||||||
|
#[inline]
|
||||||
pub fn swap(&mut self, a_index: usize, b_index: usize) {
|
pub fn swap(&mut self, a_index: usize, b_index: usize) {
|
||||||
self.0.swap(a_index, b_index);
|
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).
|
/// 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).
|
/// See also [`sort_by_key`](Children::sort_by_key), [`sort_by_cached_key`](Children::sort_by_cached_key).
|
||||||
|
#[inline]
|
||||||
pub fn sort_by<F>(&mut self, compare: F)
|
pub fn sort_by<F>(&mut self, compare: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&Entity, &Entity) -> std::cmp::Ordering,
|
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).
|
/// 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).
|
/// See also [`sort_by`](Children::sort_by), [`sort_by_cached_key`](Children::sort_by_cached_key).
|
||||||
|
#[inline]
|
||||||
pub fn sort_by_key<K, F>(&mut self, compare: F)
|
pub fn sort_by_key<K, F>(&mut self, compare: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&Entity) -> K,
|
F: FnMut(&Entity) -> K,
|
||||||
@ -95,6 +100,7 @@ impl Children {
|
|||||||
/// For the underlying implementation, see [`slice::sort_by_cached_key`].
|
/// For the underlying implementation, see [`slice::sort_by_cached_key`].
|
||||||
///
|
///
|
||||||
/// See also [`sort_by`](Children::sort_by), [`sort_by_key`](Children::sort_by_key).
|
/// See also [`sort_by`](Children::sort_by), [`sort_by_key`](Children::sort_by_key).
|
||||||
|
#[inline]
|
||||||
pub fn sort_by_cached_key<K, F>(&mut self, compare: F)
|
pub fn sort_by_cached_key<K, F>(&mut self, compare: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&Entity) -> K,
|
F: FnMut(&Entity) -> K,
|
||||||
@ -111,6 +117,7 @@ impl Children {
|
|||||||
/// For the stable version, see [`sort_by`](Children::sort_by).
|
/// For the stable version, see [`sort_by`](Children::sort_by).
|
||||||
///
|
///
|
||||||
/// See also [`sort_unstable_by_key`](Children::sort_unstable_by_key).
|
/// See also [`sort_unstable_by_key`](Children::sort_unstable_by_key).
|
||||||
|
#[inline]
|
||||||
pub fn sort_unstable_by<F>(&mut self, compare: F)
|
pub fn sort_unstable_by<F>(&mut self, compare: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&Entity, &Entity) -> std::cmp::Ordering,
|
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).
|
/// For the stable version, see [`sort_by_key`](Children::sort_by_key).
|
||||||
///
|
///
|
||||||
/// See also [`sort_unstable_by`](Children::sort_unstable_by).
|
/// See also [`sort_unstable_by`](Children::sort_unstable_by).
|
||||||
|
#[inline]
|
||||||
pub fn sort_unstable_by_key<K, F>(&mut self, compare: F)
|
pub fn sort_unstable_by_key<K, F>(&mut self, compare: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&Entity) -> K,
|
F: FnMut(&Entity) -> K,
|
||||||
@ -138,6 +146,7 @@ impl Children {
|
|||||||
impl Deref for Children {
|
impl Deref for Children {
|
||||||
type Target = [Entity];
|
type Target = [Entity];
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.0[..]
|
&self.0[..]
|
||||||
}
|
}
|
||||||
@ -148,6 +157,7 @@ impl<'a> IntoIterator for &'a Children {
|
|||||||
|
|
||||||
type IntoIter = slice::Iter<'a, Entity>;
|
type IntoIter = slice::Iter<'a, Entity>;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
self.0.iter()
|
self.0.iter()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ pub struct Parent(pub(crate) Entity);
|
|||||||
|
|
||||||
impl Parent {
|
impl Parent {
|
||||||
/// Gets the [`Entity`] ID of the parent.
|
/// Gets the [`Entity`] ID of the parent.
|
||||||
|
#[inline(always)]
|
||||||
pub fn get(&self) -> Entity {
|
pub fn get(&self) -> Entity {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
@ -37,6 +38,7 @@ impl Parent {
|
|||||||
/// for both [`Children`] & [`Parent`] that is agnostic to edge direction.
|
/// for both [`Children`] & [`Parent`] that is agnostic to edge direction.
|
||||||
///
|
///
|
||||||
/// [`Children`]: super::children::Children
|
/// [`Children`]: super::children::Children
|
||||||
|
#[inline(always)]
|
||||||
pub fn as_slice(&self) -> &[Entity] {
|
pub fn as_slice(&self) -> &[Entity] {
|
||||||
std::slice::from_ref(&self.0)
|
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
|
// However Parent should only ever be set with a real user-defined entity. Its worth looking into
|
||||||
// better ways to handle cases like this.
|
// better ways to handle cases like this.
|
||||||
impl FromWorld for Parent {
|
impl FromWorld for Parent {
|
||||||
|
#[inline(always)]
|
||||||
fn from_world(_world: &mut World) -> Self {
|
fn from_world(_world: &mut World) -> Self {
|
||||||
Parent(Entity::PLACEHOLDER)
|
Parent(Entity::PLACEHOLDER)
|
||||||
}
|
}
|
||||||
@ -61,6 +64,7 @@ impl MapEntities for Parent {
|
|||||||
impl Deref for Parent {
|
impl Deref for Parent {
|
||||||
type Target = Entity;
|
type Target = Entity;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user