Rollup merge of #49496 - glandium:master, r=sfackler
Add more vec![... ; n] optimizations vec![0; n], via implementations of SpecFromElem, has an optimization that uses with_capacity_zeroed instead of with_capacity, which will use calloc instead of malloc, and avoid an extra memset. This PR adds the same optimization for ptr::null, ptr::null_mut, and None, when their in-memory representation is zeroes.
This commit is contained in:
commit
23689cc8e9
1 changed files with 57 additions and 28 deletions
|
@ -1594,40 +1594,69 @@ impl SpecFromElem for u8 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_spec_from_elem {
|
impl<T: Clone + IsZero> SpecFromElem for T {
|
||||||
($t: ty, $is_zero: expr) => {
|
#[inline]
|
||||||
impl SpecFromElem for $t {
|
fn from_elem(elem: T, n: usize) -> Vec<T> {
|
||||||
#[inline]
|
if elem.is_zero() {
|
||||||
fn from_elem(elem: $t, n: usize) -> Vec<$t> {
|
return Vec {
|
||||||
if $is_zero(elem) {
|
buf: RawVec::with_capacity_zeroed(n),
|
||||||
return Vec {
|
len: n,
|
||||||
buf: RawVec::with_capacity_zeroed(n),
|
|
||||||
len: n,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut v = Vec::with_capacity(n);
|
|
||||||
v.extend_with(n, ExtendElement(elem));
|
|
||||||
v
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
let mut v = Vec::with_capacity(n);
|
||||||
|
v.extend_with(n, ExtendElement(elem));
|
||||||
|
v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_spec_from_elem!(i8, |x| x == 0);
|
unsafe trait IsZero {
|
||||||
impl_spec_from_elem!(i16, |x| x == 0);
|
/// Whether this value is zero
|
||||||
impl_spec_from_elem!(i32, |x| x == 0);
|
fn is_zero(&self) -> bool;
|
||||||
impl_spec_from_elem!(i64, |x| x == 0);
|
}
|
||||||
impl_spec_from_elem!(i128, |x| x == 0);
|
|
||||||
impl_spec_from_elem!(isize, |x| x == 0);
|
|
||||||
|
|
||||||
impl_spec_from_elem!(u16, |x| x == 0);
|
macro_rules! impl_is_zero {
|
||||||
impl_spec_from_elem!(u32, |x| x == 0);
|
($t: ty, $is_zero: expr) => {
|
||||||
impl_spec_from_elem!(u64, |x| x == 0);
|
unsafe impl IsZero for $t {
|
||||||
impl_spec_from_elem!(u128, |x| x == 0);
|
#[inline]
|
||||||
impl_spec_from_elem!(usize, |x| x == 0);
|
fn is_zero(&self) -> bool {
|
||||||
|
$is_zero(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_is_zero!(i8, |x| x == 0);
|
||||||
|
impl_is_zero!(i16, |x| x == 0);
|
||||||
|
impl_is_zero!(i32, |x| x == 0);
|
||||||
|
impl_is_zero!(i64, |x| x == 0);
|
||||||
|
impl_is_zero!(i128, |x| x == 0);
|
||||||
|
impl_is_zero!(isize, |x| x == 0);
|
||||||
|
|
||||||
|
impl_is_zero!(u16, |x| x == 0);
|
||||||
|
impl_is_zero!(u32, |x| x == 0);
|
||||||
|
impl_is_zero!(u64, |x| x == 0);
|
||||||
|
impl_is_zero!(u128, |x| x == 0);
|
||||||
|
impl_is_zero!(usize, |x| x == 0);
|
||||||
|
|
||||||
|
impl_is_zero!(char, |x| x == '\0');
|
||||||
|
|
||||||
|
impl_is_zero!(f32, |x: f32| x.to_bits() == 0);
|
||||||
|
impl_is_zero!(f64, |x: f64| x.to_bits() == 0);
|
||||||
|
|
||||||
|
unsafe impl<T: ?Sized> IsZero for *const T {
|
||||||
|
#[inline]
|
||||||
|
fn is_zero(&self) -> bool {
|
||||||
|
(*self).is_null()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: ?Sized> IsZero for *mut T {
|
||||||
|
#[inline]
|
||||||
|
fn is_zero(&self) -> bool {
|
||||||
|
(*self).is_null()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_spec_from_elem!(f32, |x: f32| x.to_bits() == 0);
|
|
||||||
impl_spec_from_elem!(f64, |x: f64| x.to_bits() == 0);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Common trait implementations for Vec
|
// Common trait implementations for Vec
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue