From 768ddf1ae6703cc1f5f57a9c036efe1a231b0a1d Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 7 Jul 2024 23:39:52 +0300 Subject: [PATCH] sparkle some #[inline] --- src/arc.rs | 25 +++++++++++++++++++++++++ src/arena.rs | 30 +++++++++++++++++++++++++++--- src/boxedset.rs | 6 ++++++ src/intern.rs | 27 ++++++++++++++++++++++++--- src/typearena.rs | 26 +++++++++++++++++++++++--- 5 files changed, 105 insertions(+), 9 deletions(-) diff --git a/src/arc.rs b/src/arc.rs index 0e92b3b..25b40b0 100644 --- a/src/arc.rs +++ b/src/arc.rs @@ -49,6 +49,7 @@ pub struct ArcIntern { #[cfg(feature = "deepsize")] impl deepsize::DeepSizeOf for ArcIntern { + #[inline(always)] fn deep_size_of_children(&self, _context: &mut deepsize::Context) -> usize { 0 } @@ -80,11 +81,13 @@ pub(crate) struct RefCount { impl Eq for RefCount {} impl PartialEq for RefCount { + #[inline] fn eq(&self, other: &Self) -> bool { self.data == other.data } } impl Hash for RefCount { + #[inline] fn hash(&self, hasher: &mut H) { self.data.hash(hasher) } @@ -93,28 +96,33 @@ impl Hash for RefCount { #[derive(Eq, PartialEq)] pub(crate) struct BoxRefCount(pub Box>); impl Hash for BoxRefCount { + #[inline] fn hash(&self, hasher: &mut H) { self.0.data.hash(hasher) } } impl BoxRefCount { + #[inline(always)] fn into_inner(self) -> T { self.0.data } } impl Borrow for BoxRefCount { + #[inline(always)] fn borrow(&self) -> &T { &self.0.data } } impl Borrow> for BoxRefCount { + #[inline(always)] fn borrow(&self) -> &RefCount { &self.0 } } impl Deref for BoxRefCount { + #[inline(always)] type Target = T; fn deref(&self) -> &Self::Target { &self.0.data @@ -122,6 +130,7 @@ impl Deref for BoxRefCount { } impl ArcIntern { + #[inline(always)] fn get_pointer(&self) -> *const RefCount { self.pointer.as_ptr() } @@ -299,6 +308,7 @@ impl Drop for ArcIntern { } impl AsRef for ArcIntern { + #[inline(always)] fn as_ref(&self) -> &T { unsafe { &self.pointer.as_ref().data } } @@ -306,18 +316,21 @@ impl AsRef for ArcIntern { impl Deref for ArcIntern { type Target = T; + #[inline(always)] fn deref(&self) -> &T { self.as_ref() } } impl Display for ArcIntern { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { self.deref().fmt(f) } } impl Pointer for ArcIntern { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { Pointer::fmt(&self.get_pointer(), f) } @@ -329,12 +342,14 @@ impl Pointer for ArcIntern { /// value, but it *is* observable, since you could compare the /// hash of the pointer with hash of the data itself. impl Hash for ArcIntern { + #[inline] fn hash(&self, state: &mut H) { self.get_pointer().hash(state); } } impl PartialEq for ArcIntern { + #[inline(always)] fn eq(&self, other: &Self) -> bool { self.get_pointer() == other.get_pointer() } @@ -342,23 +357,29 @@ impl PartialEq for ArcIntern { impl Eq for ArcIntern {} impl PartialOrd for ArcIntern { + #[inline] fn partial_cmp(&self, other: &Self) -> Option { self.as_ref().partial_cmp(other) } + #[inline] fn lt(&self, other: &Self) -> bool { self.as_ref().lt(other) } + #[inline] fn le(&self, other: &Self) -> bool { self.as_ref().le(other) } + #[inline] fn gt(&self, other: &Self) -> bool { self.as_ref().gt(other) } + #[inline] fn ge(&self, other: &Self) -> bool { self.as_ref().ge(other) } } impl Ord for ArcIntern { + #[inline] fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.as_ref().cmp(other) } @@ -367,18 +388,21 @@ impl Ord for ArcIntern { #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] #[cfg(feature = "serde")] impl Serialize for ArcIntern { + #[inline] fn serialize(&self, serializer: S) -> Result { self.as_ref().serialize(serializer) } } impl From for ArcIntern { + #[inline] fn from(t: T) -> Self { ArcIntern::new(t) } } impl Default for ArcIntern { + #[inline] fn default() -> Self { ArcIntern::new(Default::default()) } @@ -390,6 +414,7 @@ impl<'de, T> Deserialize<'de> for ArcIntern where T: Eq + Hash + Send + Sync + 'static + Deserialize<'de>, { + #[inline] fn deserialize>(deserializer: D) -> Result { T::deserialize(deserializer).map(|x: T| Self::new(x)) } diff --git a/src/arena.rs b/src/arena.rs index dbfca93..09ee130 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -64,16 +64,16 @@ impl<'a, T: ?Sized + deepsize::DeepSizeOf> deepsize::DeepSizeOf for ArenaIntern< } impl<'a, T: ?Sized> Clone for ArenaIntern<'a, T> { + #[inline(always)] fn clone(&self) -> Self { - ArenaIntern { - pointer: self.pointer, - } + *self } } impl<'a, T: ?Sized> Copy for ArenaIntern<'a, T> {} impl Arena { /// Allocate a new `Arena` + #[inline] pub fn new() -> Self { Arena { data: Mutex::new(HashSet::new()), @@ -150,6 +150,7 @@ impl Arena { /// If this value has not previously been interned, then `intern` will /// allocate a spot for the value on the heap. Otherwise, it will return a /// pointer to the `str` previously allocated. + #[inline] pub fn intern<'a, 'b>(&'a self, val: &'b str) -> ArenaIntern<'a, str> { self.intern_ref(val) } @@ -158,6 +159,7 @@ impl Arena { /// If this value has not previously been interned, then `intern` will save /// the provided `String`. Otherwise, it will free its input `String` and /// return a pointer to the `str` previously saved. + #[inline] pub fn intern_string(&self, val: String) -> ArenaIntern { self.intern_from_owned(val) } @@ -166,6 +168,7 @@ impl Arena { /// If this value has not previously been interned, then `intern` will save /// the provided `Box`. Otherwise, it will free its input `Box` /// and return a pointer to the `str` previously saved. + #[inline] pub fn intern_box(&self, val: Box) -> ArenaIntern { self.intern_from_owned(val) } @@ -185,6 +188,7 @@ impl Arena { /// let y = arena.intern(std::ffi::CString::new("hello").unwrap().as_c_str()); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern<'a, 'b>(&'a self, val: &'b std::ffi::CStr) -> ArenaIntern<'a, std::ffi::CStr> { self.intern_ref(val) } @@ -202,6 +206,7 @@ impl Arena { /// let y = arena.intern_cstring(std::ffi::CString::new("hello").unwrap()); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern_cstring(&self, val: std::ffi::CString) -> ArenaIntern { self.intern_from_owned(val) } @@ -219,6 +224,7 @@ impl Arena { /// let y = arena.intern_box(std::ffi::CString::new("hello").unwrap().into_boxed_c_str()); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern_box(&self, val: Box) -> ArenaIntern { self.intern_from_owned(val) } @@ -238,6 +244,7 @@ impl Arena { /// let y = arena.intern(std::ffi::OsStr::new("hello")); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern<'a, 'b>(&'a self, val: &'b std::ffi::OsStr) -> ArenaIntern<'a, std::ffi::OsStr> { self.intern_ref(val) } @@ -255,6 +262,7 @@ impl Arena { /// let y = arena.intern_osstring(std::ffi::OsString::from("hello")); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern_osstring(&self, val: std::ffi::OsString) -> ArenaIntern { self.intern_from_owned(val) } @@ -272,6 +280,7 @@ impl Arena { /// let y = arena.intern_box(std::ffi::OsString::from("hello").into_boxed_os_str()); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern_box(&self, val: Box) -> ArenaIntern { self.intern_from_owned(val) } @@ -291,6 +300,7 @@ impl Arena { /// let y = arena.intern(std::path::Path::new("hello")); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern<'a, 'b>(&'a self, val: &'b std::path::Path) -> ArenaIntern<'a, std::path::Path> { self.intern_ref(val) } @@ -308,6 +318,7 @@ impl Arena { /// let y = arena.intern_pathbuf(std::path::PathBuf::from("hello")); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern_pathbuf(&self, val: std::path::PathBuf) -> ArenaIntern { self.intern_from_owned(val) } @@ -325,6 +336,7 @@ impl Arena { /// let y = arena.intern_box(std::path::PathBuf::from("hello").into_boxed_path()); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern_box(&self, val: Box) -> ArenaIntern { self.intern_from_owned(val) } @@ -335,6 +347,7 @@ impl Arena<[T]> { /// If this value has not previously been interned, then `intern` will /// allocate a spot for the value on the heap. Otherwise, it will return a /// pointer to the `[T]` previously allocated. + #[inline] pub fn intern<'a, 'b>(&'a self, val: &'b [T]) -> ArenaIntern<'a, [T]> { self.intern_ref(val) } @@ -343,6 +356,7 @@ impl Arena<[T]> { /// If this value has not previously been interned, then `intern` will save /// the provided `Vec`. Otherwise, it will free its input `Vec` and /// return a pointer to the `[T]` previously saved. + #[inline] pub fn intern_vec(&self, val: Vec) -> ArenaIntern<[T]> { self.intern_from_owned(val) } @@ -351,6 +365,7 @@ impl Arena<[T]> { /// If this value has not previously been interned, then `intern` will save /// the provided `Box`. Otherwise, it will free its input `Box<[T]>` /// and return a pointer to the `[T]` previously saved. + #[inline] pub fn intern_box(&self, val: Box<[T]>) -> ArenaIntern<[T]> { self.intern_from_owned(val) } @@ -379,12 +394,14 @@ impl Arena { } impl Default for Arena { + #[inline] fn default() -> Self { Self::new() } } impl<'a, T: ?Sized> AsRef for ArenaIntern<'a, T> { + #[inline(always)] fn as_ref(&self) -> &T { self.pointer } @@ -392,12 +409,14 @@ impl<'a, T: ?Sized> AsRef for ArenaIntern<'a, T> { impl<'a, T: ?Sized> std::ops::Deref for ArenaIntern<'a, T> { type Target = T; + #[inline(always)] fn deref(&self) -> &Self::Target { self.as_ref() } } impl<'a, T: ?Sized> ArenaIntern<'a, T> { + #[inline(always)] fn get_pointer(&self) -> *const T { self.pointer as *const T } @@ -456,6 +475,7 @@ impl<'a, T: ?Sized> ArenaIntern<'a, T> { /// } /// } /// ``` + #[inline(always)] pub fn into_ref(self) -> &'a T { self.pointer } @@ -467,12 +487,14 @@ impl<'a, T: ?Sized> ArenaIntern<'a, T> { /// value, but it *is* observable, since you could compare the /// hash of the pointer with hash of the data itself. impl<'a, T: ?Sized> Hash for ArenaIntern<'a, T> { + #[inline] fn hash(&self, state: &mut H) { self.get_pointer().hash(state); } } impl<'a, T: ?Sized> PartialEq for ArenaIntern<'a, T> { + #[inline] fn eq(&self, other: &Self) -> bool { self.get_pointer() == other.get_pointer() } @@ -483,12 +505,14 @@ impl<'a, T: ?Sized> Eq for ArenaIntern<'a, T> {} // create_impls_no_new!(ArenaIntern, arenaintern_impl_tests, ['a], [Eq, Hash], [Eq, Hash]); impl<'a, T: std::fmt::Debug + ?Sized> std::fmt::Debug for ArenaIntern<'a, T> { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { self.as_ref().fmt(f) } } impl<'a, T: std::fmt::Display + ?Sized> std::fmt::Display for ArenaIntern<'a, T> { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { self.as_ref().fmt(f) } diff --git a/src/boxedset.rs b/src/boxedset.rs index 15c98ec..c5a3b5d 100644 --- a/src/boxedset.rs +++ b/src/boxedset.rs @@ -7,11 +7,13 @@ use std::{ pub struct HashSet

(HashMap); impl Default for HashSet

{ + #[inline] fn default() -> Self { HashSet::new() } } impl

HashSet

{ + #[inline] pub fn new() -> Self { HashSet(HashMap::new()) } @@ -71,17 +73,21 @@ impl HashSet

{ // }; // let x = self.0.raw_entry_mut().from_hash(hash, |k| >::borrow(k) == key) } + #[inline] pub fn insert(&mut self, x: P) { self.0.insert(x, ()); } + #[inline] pub fn len(&self) -> usize { self.0.len() } #[allow(dead_code)] // maybe unused without `deepsize` feature + #[inline] pub fn capacity(&self) -> usize { self.0.capacity() } #[cfg(feature = "bench")] + #[inline] pub fn clear(&mut self) { self.0.clear() } diff --git a/src/intern.rs b/src/intern.rs index 3ed38f9..82d0758 100644 --- a/src/intern.rs +++ b/src/intern.rs @@ -6,6 +6,7 @@ use std::convert::AsRef; use std::fmt::{Debug, Display, Pointer}; use std::hash::{Hash, Hasher}; use std::ops::Deref; +use std::ptr; use super::container; @@ -91,10 +92,9 @@ fn has_niche() { } impl Clone for Intern { + #[inline(always)] fn clone(&self) -> Self { - Intern { - pointer: self.pointer, - } + *self } } @@ -103,6 +103,7 @@ impl Clone for Intern { impl Copy for Intern {} impl Intern { + #[inline(always)] fn get_pointer(&self) -> *const T { self.pointer as *const T } @@ -113,6 +114,7 @@ static INTERN_CONTAINERS: container::Arena = container::Arena::new(); macro_rules! from_via_box { ($t:ty) => { impl From<&$t> for Intern<$t> { + #[inline] fn from(val: &$t) -> Self { Self::via_box(val) } @@ -123,6 +125,7 @@ from_via_box!(std::ffi::CStr); from_via_box!(str); from_via_box!(std::path::Path); impl From<&[T]> for Intern<[T]> { + #[inline] fn from(val: &[T]) -> Self { Self::via_box(val) } @@ -130,6 +133,7 @@ impl From<&[T]> for Intern<[T]> { impl From<&[T; N]> for Intern<[T]> { /// Converts a `[T; N]` into a `Intern<[T]>` + #[inline] fn from(val: &[T; N]) -> Self { Self::via_box(val) } @@ -228,6 +232,7 @@ impl Intern { impl Intern { /// Get a long-lived reference to the data pointed to by an `Intern`, which /// is never freed from the intern pool. + #[inline(always)] pub fn as_ref(self) -> &'static T { self.pointer } @@ -322,6 +327,7 @@ fn test_intern_set64() { } impl AsRef for Intern { + #[inline(always)] fn as_ref(&self) -> &T { self.pointer } @@ -329,18 +335,21 @@ impl AsRef for Intern { impl Deref for Intern { type Target = T; + #[inline(always)] fn deref(&self) -> &T { self.as_ref() } } impl Display for Intern { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { self.deref().fmt(f) } } impl Pointer for Intern { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { Pointer::fmt(&self.get_pointer(), f) } @@ -352,12 +361,14 @@ impl Pointer for Intern { /// value, but it *is* observable, since you could compare the /// hash of the pointer with hash of the data itself. impl Hash for Intern { + #[inline] fn hash(&self, state: &mut H) { self.get_pointer().hash(state); } } impl PartialEq for Intern { + #[inline] fn eq(&self, other: &Self) -> bool { std::ptr::eq(self.get_pointer(), other.get_pointer()) } @@ -365,23 +376,29 @@ impl PartialEq for Intern { impl Eq for Intern {} impl PartialOrd for Intern { + #[inline] fn partial_cmp(&self, other: &Self) -> Option { self.as_ref().partial_cmp(other) } + #[inline] fn lt(&self, other: &Self) -> bool { self.as_ref().lt(other) } + #[inline] fn le(&self, other: &Self) -> bool { self.as_ref().le(other) } + #[inline] fn gt(&self, other: &Self) -> bool { self.as_ref().gt(other) } + #[inline] fn ge(&self, other: &Self) -> bool { self.as_ref().ge(other) } } impl Ord for Intern { + #[inline] fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.as_ref().cmp(other) } @@ -390,17 +407,20 @@ impl Ord for Intern { #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] #[cfg(feature = "serde")] impl Serialize for Intern { + #[inline] fn serialize(&self, serializer: S) -> Result { self.as_ref().serialize(serializer) } } impl From for Intern { + #[inline] fn from(t: T) -> Self { Intern::new(t) } } impl Default for Intern { + #[inline] fn default() -> Self { Intern::new(Default::default()) } @@ -631,6 +651,7 @@ mod intern_tests { } impl Debug for Intern { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { self.as_ref().fmt(f) } diff --git a/src/typearena.rs b/src/typearena.rs index 82bdec2..037ebfe 100644 --- a/src/typearena.rs +++ b/src/typearena.rs @@ -149,10 +149,9 @@ fn has_niche() { } impl Clone for Intern { + #[inline(always)] fn clone(&self) -> Self { - Intern { - pointer: self.pointer, - } + *self } } @@ -161,6 +160,7 @@ impl Clone for Intern { impl Copy for Intern {} impl Intern { + #[inline(always)] fn get_pointer(&self) -> *const T { self.pointer as *const T } @@ -169,6 +169,7 @@ impl Intern { macro_rules! from_via_box { ($t:ty) => { impl From<&$t> for Intern<$t> { + #[inline] fn from(val: &$t) -> Self { Self::via_box(val) } @@ -179,6 +180,7 @@ from_via_box!(std::ffi::CStr); from_via_box!(str); from_via_box!(std::path::Path); impl From<&[T]> for Intern<[T]> { + #[inline] fn from(val: &[T]) -> Self { Self::via_box(val) } @@ -186,6 +188,7 @@ impl From<&[T]> for Intern<[T]> { impl From<&[T; N]> for Intern<[T]> { /// Converts a `[T; N]` into a `Intern<[T]>` + #[inline] fn from(val: &[T; N]) -> Self { Self::via_box(val) } @@ -278,6 +281,7 @@ impl Intern { impl Intern { /// Get a long-lived reference to the data pointed to by an `Intern`, which /// is never freed from the intern pool. + #[inline(always)] pub fn as_ref(self) -> &'static T { self.pointer } @@ -363,6 +367,7 @@ fn test_intern_set64() { } impl AsRef for Intern { + #[inline(always)] fn as_ref(&self) -> &T { self.pointer } @@ -370,18 +375,21 @@ impl AsRef for Intern { impl Deref for Intern { type Target = T; + #[inline(always)] fn deref(&self) -> &T { self.as_ref() } } impl Display for Intern { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { self.deref().fmt(f) } } impl Pointer for Intern { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { Pointer::fmt(&self.get_pointer(), f) } @@ -393,12 +401,14 @@ impl Pointer for Intern { /// value, but it *is* observable, since you could compare the /// hash of the pointer with hash of the data itself. impl Hash for Intern { + #[inline] fn hash(&self, state: &mut H) { self.get_pointer().hash(state); } } impl PartialEq for Intern { + #[inline(always)] fn eq(&self, other: &Self) -> bool { self.get_pointer() == other.get_pointer() } @@ -406,23 +416,29 @@ impl PartialEq for Intern { impl Eq for Intern {} impl PartialOrd for Intern { + #[inline] fn partial_cmp(&self, other: &Self) -> Option { self.as_ref().partial_cmp(other) } + #[inline] fn lt(&self, other: &Self) -> bool { self.as_ref().lt(other) } + #[inline] fn le(&self, other: &Self) -> bool { self.as_ref().le(other) } + #[inline] fn gt(&self, other: &Self) -> bool { self.as_ref().gt(other) } + #[inline] fn ge(&self, other: &Self) -> bool { self.as_ref().ge(other) } } impl Ord for Intern { + #[inline] fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.as_ref().cmp(other) } @@ -431,17 +447,20 @@ impl Ord for Intern { #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] #[cfg(feature = "serde")] impl Serialize for Intern { + #[inline] fn serialize(&self, serializer: S) -> Result { self.as_ref().serialize(serializer) } } impl From for Intern { + #[inline] fn from(t: T) -> Self { Intern::new(t) } } impl Default for Intern { + #[inline] fn default() -> Self { Intern::new(Default::default()) } @@ -450,6 +469,7 @@ impl Default for Intern { #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] #[cfg(feature = "serde")] impl<'de, T: Eq + Hash + Send + Sync + 'static + Deserialize<'de>> Deserialize<'de> for Intern { + #[inline] fn deserialize>(deserializer: D) -> Result { T::deserialize(deserializer).map(|x: T| Self::new(x)) }