Skip to content

Commit

Permalink
fix: performance regression using #[repr(usize)] on amd64
Browse files Browse the repository at this point in the history
  • Loading branch information
PureWhiteWu committed Dec 24, 2023
1 parent e26bd65 commit 342bdc9
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "faststr"
version = "0.2.14"
version = "0.2.15"
authors = ["Volo Team <volo@cloudwego.io>"]
edition = "2021"
description = "Faststr is a string library that reduces the cost of clone."
Expand Down
33 changes: 12 additions & 21 deletions src/lib.rs
Expand Up @@ -263,10 +263,7 @@ impl FastStr {
ch.encode_utf8(&mut buf[len..]);
len += size;
}
Self(Repr::Inline {
len: len as u8,
buf,
})
Self(Repr::Inline { len, buf })
}
}

Expand Down Expand Up @@ -443,10 +440,7 @@ where
buf[len..][..size].copy_from_slice(slice.as_bytes());
len += size;
}
FastStr(Repr::Inline {
len: len as u8,
buf,
})
FastStr(Repr::Inline { len, buf })
}

impl iter::FromIterator<String> for FastStr {
Expand Down Expand Up @@ -535,17 +529,16 @@ impl From<Cow<'static, str>> for FastStr {
}
}

const INLINE_CAP: usize = 30;
const INLINE_CAP: usize = 24;

#[derive(Clone)]
#[repr(usize)]
enum Repr {
Empty,
Bytes(Bytes),
ArcStr(Arc<str>),
ArcString(Arc<String>),
StaticStr(&'static str),
Inline { len: u8, buf: [u8; INLINE_CAP] },
Inline { len: usize, buf: [u8; INLINE_CAP] },
}

impl Repr {
Expand Down Expand Up @@ -583,7 +576,7 @@ impl Repr {
unsafe fn new_inline_impl(s: &str) -> Self {
#[allow(invalid_value, clippy::uninit_assumed_init)]
let mut inl = Self::Inline {
len: s.len() as u8,
len: s.len(),
buf: MaybeUninit::uninit().assume_init(),
};
match inl {
Expand All @@ -593,7 +586,7 @@ impl Repr {
} => {
// We can't guarantee if it's nonoverlapping here, so we can only use std::ptr::copy.
std::ptr::copy(s.as_ptr(), buf.as_mut_ptr(), s.len());
*len = s.len() as u8;
*len = s.len();
}
_ => unreachable_unchecked(),
}
Expand Down Expand Up @@ -639,7 +632,7 @@ impl Repr {
Self::ArcStr(arc_str) => arc_str.len(),
Self::ArcString(arc_string) => arc_string.len(),
Self::StaticStr(s) => s.len(),
Self::Inline { len, .. } => *len as usize,
Self::Inline { len, .. } => *len,
}
}

Expand All @@ -664,9 +657,7 @@ impl Repr {
Self::ArcStr(arc_str) => arc_str,
Self::ArcString(arc_string) => arc_string,
Self::StaticStr(s) => s,
Self::Inline { len, buf } => unsafe {
std::str::from_utf8_unchecked(&buf[..*len as usize])
},
Self::Inline { len, buf } => unsafe { std::str::from_utf8_unchecked(&buf[..*len]) },
}
}

Expand All @@ -682,7 +673,7 @@ impl Repr {
}
Self::StaticStr(s) => s.to_string(),
Self::Inline { len, buf } => unsafe {
String::from_utf8_unchecked(buf[..len as usize].to_vec())
String::from_utf8_unchecked(buf[..len].to_vec())
},
}
}
Expand All @@ -697,7 +688,7 @@ impl Repr {
Bytes::from(Arc::try_unwrap(arc_string).unwrap_or_else(|arc| (*arc).clone()))
}
Self::StaticStr(s) => Bytes::from_static(s.as_bytes()),
Self::Inline { len, buf } => Bytes::from(buf[..len as usize].to_vec()),
Self::Inline { len, buf } => Bytes::from(buf[..len].to_vec()),
}
}

Expand Down Expand Up @@ -741,7 +732,7 @@ impl Repr {
std::str::from_utf8_unchecked(&s.as_bytes()[sub_offset..sub_offset + sub_len])
}),
Repr::Inline { len: _, buf } => Self::Inline {
len: sub_len as u8,
len: sub_len,
buf: {
let mut new_buf = [0; INLINE_CAP];
new_buf[..sub_len].copy_from_slice(&buf[sub_offset..sub_offset + sub_len]);
Expand All @@ -761,7 +752,7 @@ impl AsRef<[u8]> for Repr {
Self::ArcStr(arc_str) => arc_str.as_bytes(),
Self::ArcString(arc_string) => arc_string.as_bytes(),
Self::StaticStr(s) => s.as_bytes(),
Self::Inline { len, buf } => &buf[..*len as usize],
Self::Inline { len, buf } => &buf[..*len],
}
}
}
Expand Down

0 comments on commit 342bdc9

Please sign in to comment.