Auto merge of #89069 - bjorn3:optimize_sharded_new, r=Mark-Simulacrum

Use <[T; N]>::map in Sharded instead of SmallVec and unsafe code

This results in a lot less assembly
This commit is contained in:
bors 2021-09-20 14:33:00 +00:00
commit 3bb9eecf07

View file

@ -1,6 +1,5 @@
use crate::fx::{FxHashMap, FxHasher}; use crate::fx::{FxHashMap, FxHasher};
use crate::sync::{Lock, LockGuard}; use crate::sync::{Lock, LockGuard};
use smallvec::SmallVec;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::collections::hash_map::RawEntryMut; use std::collections::hash_map::RawEntryMut;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
@ -37,24 +36,7 @@ impl<T: Default> Default for Sharded<T> {
impl<T> Sharded<T> { impl<T> Sharded<T> {
#[inline] #[inline]
pub fn new(mut value: impl FnMut() -> T) -> Self { pub fn new(mut value: impl FnMut() -> T) -> Self {
// Create a vector of the values we want Sharded { shards: [(); SHARDS].map(|()| CacheAligned(Lock::new(value()))) }
let mut values: SmallVec<[_; SHARDS]> =
(0..SHARDS).map(|_| CacheAligned(Lock::new(value()))).collect();
// Create an uninitialized array
let mut shards: mem::MaybeUninit<[CacheAligned<Lock<T>>; SHARDS]> =
mem::MaybeUninit::uninit();
unsafe {
// Copy the values into our array
let first = shards.as_mut_ptr() as *mut CacheAligned<Lock<T>>;
values.as_ptr().copy_to_nonoverlapping(first, SHARDS);
// Ignore the content of the vector
values.set_len(0);
Sharded { shards: shards.assume_init() }
}
} }
/// The shard is selected by hashing `val` with `FxHasher`. /// The shard is selected by hashing `val` with `FxHasher`.