From fd682be902665c591c6c6036417078cd6aad2d49 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 | 26 ++++++++++++++++++++++++++ src/boxedset.rs | 6 ++++++ src/intern.rs | 23 ++++++++++++++++++++++- src/typearena.rs | 22 ++++++++++++++++++++++ 5 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/arc.rs b/src/arc.rs index 6f0d69e..9757c60 100644 --- a/src/arc.rs +++ b/src/arc.rs @@ -51,6 +51,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 } @@ -82,11 +83,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) } @@ -95,35 +98,41 @@ 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 { type Target = T; + #[inline(always)] fn deref(&self) -> &Self::Target { &self.0.data } } impl ArcIntern { + #[inline(always)] fn get_pointer(&self) -> *const RefCount { self.pointer.as_ptr() } @@ -302,6 +311,7 @@ impl Drop for ArcIntern { } impl AsRef for ArcIntern { + #[inline(always)] fn as_ref(&self) -> &T { unsafe { &self.pointer.as_ref().data } } @@ -326,18 +336,21 @@ impl_as_ref!(Path => OsStr); 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) } @@ -349,12 +362,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 { std::ptr::eq(self.get_pointer(), other.get_pointer()) } @@ -362,23 +377,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) } @@ -387,18 +408,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()) } @@ -410,6 +434,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 248b1e4..647d8dc 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -64,6 +64,7 @@ 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 { *self } @@ -72,6 +73,7 @@ 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()), @@ -148,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>(&'a self, val: &str) -> ArenaIntern<'a, str> { self.intern_ref(val) } @@ -156,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) } @@ -164,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) } @@ -183,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>(&'a self, val: &std::ffi::CStr) -> ArenaIntern<'a, std::ffi::CStr> { self.intern_ref(val) } @@ -200,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) } @@ -217,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) } @@ -236,6 +244,7 @@ impl Arena { /// let y = arena.intern(std::ffi::OsStr::new("hello")); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern<'a>(&'a self, val: &std::ffi::OsStr) -> ArenaIntern<'a, std::ffi::OsStr> { self.intern_ref(val) } @@ -253,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) } @@ -270,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) } @@ -289,6 +300,7 @@ impl Arena { /// let y = arena.intern(std::path::Path::new("hello")); /// assert_eq!(x, y); /// ``` + #[inline] pub fn intern<'a>(&'a self, val: &std::path::Path) -> ArenaIntern<'a, std::path::Path> { self.intern_ref(val) } @@ -306,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) } @@ -323,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) } @@ -333,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>(&'a self, val: &[T]) -> ArenaIntern<'a, [T]> { self.intern_ref(val) } @@ -341,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) } @@ -349,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) } @@ -377,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 } @@ -390,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 } @@ -454,6 +475,7 @@ impl<'a, T: ?Sized> ArenaIntern<'a, T> { /// } /// } /// ``` + #[inline(always)] pub fn into_ref(self) -> &'a T { self.pointer } @@ -465,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 { std::ptr::eq(self.get_pointer(), other.get_pointer()) } @@ -481,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 063efc4..de992d1 100644 --- a/src/intern.rs +++ b/src/intern.rs @@ -60,7 +60,6 @@ fn like_doctest_intern() { assert_eq!(&*x, "hello"); // dereference a Intern like a pointer\ } - #[cfg(feature = "deepsize")] impl deepsize::DeepSizeOf for Intern { fn deep_size_of_children(&self, _context: &mut deepsize::Context) -> usize { @@ -90,6 +89,7 @@ fn has_niche() { } impl Clone for Intern { + #[inline(always)] fn clone(&self) -> Self { *self } @@ -100,6 +100,7 @@ impl Clone for Intern { impl Copy for Intern {} impl Intern { + #[inline(always)] fn get_pointer(&self) -> *const T { self.pointer as *const T } @@ -110,6 +111,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) } @@ -120,6 +122,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) } @@ -127,6 +130,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) } @@ -226,6 +230,7 @@ impl Intern { /// Get a long-lived reference to the data pointed to by an `Intern`, which /// is never freed from the intern pool. #[allow(clippy::should_implement_trait)] + #[inline] pub fn as_ref(self) -> &'static T { self.pointer } @@ -320,6 +325,7 @@ fn test_intern_set64() { } impl AsRef for Intern { + #[inline(always)] fn as_ref(&self) -> &T { self.pointer } @@ -343,18 +349,21 @@ impl_as_ref!(Path => OsStr); 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) } @@ -366,12 +375,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()) } @@ -379,23 +390,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) } @@ -404,17 +421,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()) } @@ -645,6 +665,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 837348d..347b493 100644 --- a/src/typearena.rs +++ b/src/typearena.rs @@ -151,6 +151,7 @@ fn has_niche() { } impl Clone for Intern { + #[inline(always)] fn clone(&self) -> Self { *self } @@ -161,6 +162,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 +171,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 +182,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 +190,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) } @@ -279,6 +284,7 @@ impl Intern { /// Get a long-lived reference to the data pointed to by an `Intern`, which /// is never freed from the intern pool. #[allow(clippy::should_implement_trait)] + #[inline(always)] pub fn as_ref(self) -> &'static T { self.pointer } @@ -364,6 +370,7 @@ fn test_intern_set64() { } impl AsRef for Intern { + #[inline(always)] fn as_ref(&self) -> &T { self.pointer } @@ -387,18 +394,21 @@ impl_as_ref!(Path => OsStr); 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) } @@ -410,12 +420,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 { std::ptr::eq(self.get_pointer(), other.get_pointer()) } @@ -423,23 +435,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) } @@ -448,17 +466,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()) } @@ -467,6 +488,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)) }