Skip to content

Commit

Permalink
Inline short static strings (#321)
Browse files Browse the repository at this point in the history
This way short static strings have better cache locality, too.
  • Loading branch information
Kijewski authored Oct 27, 2023
1 parent 3179b03 commit f1e0649
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
17 changes: 11 additions & 6 deletions compact_str/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ impl CompactString {

/// Creates a new inline [`CompactString`] at compile time.
///
/// For most use cases you should use the method [`CompactString::from_static_str()`],
/// which will inline static strings, too, if they are short enough.
///
/// # Examples
/// ```
/// use compact_str::CompactString;
Expand All @@ -229,10 +232,9 @@ impl CompactString {
CompactString(Repr::new_inline(text))
}

/// Creates a new inline [`CompactString`] from `&'static str`
/// at compile time.
/// Creates a new inline [`CompactString`] from `&'static str` at compile time.
///
/// Complexity: O(1)
/// Complexity: O(1). As an optimization, short strings get inlined.
///
/// # Examples
/// ```
Expand All @@ -251,8 +253,12 @@ impl CompactString {
/// ```
/// use compact_str::CompactString;
///
/// const DEFAULT_NAME: CompactString = CompactString::from_static_str("untitled");
/// assert_eq!(DEFAULT_NAME.as_static_str().unwrap(), "untitled");
/// const DEFAULT_NAME: CompactString =
/// CompactString::from_static_str("That is not dead which can eternal lie.");
/// assert_eq!(
/// DEFAULT_NAME.as_static_str().unwrap(),
/// "That is not dead which can eternal lie.",
/// );
/// ```
#[inline]
#[rustversion::attr(since(1.64), const)]
Expand Down Expand Up @@ -1097,7 +1103,6 @@ impl CompactString {
///
/// assert_eq!(w, ", world!");
/// assert_eq!(s, "Hello");
/// assert_eq!(s.capacity(), 5);
/// ```
pub fn split_off(&mut self, at: usize) -> Self {
if let Some(s) = self.as_static_str() {
Expand Down
11 changes: 8 additions & 3 deletions compact_str/src/repr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,14 @@ impl Repr {

#[inline]
pub const fn from_static_str(text: &'static str) -> Self {
let repr = StaticStr::new(text);
// SAFETY: A `StaticStr` and `Repr` have the same size
unsafe { core::mem::transmute(repr) }
if text.len() <= MAX_SIZE {
let inline = InlineBuffer::new_const(text);
Self::from_inline(inline)
} else {
let repr = StaticStr::new(text);
// SAFETY: A `StaticStr` and `Repr` have the same size
unsafe { core::mem::transmute(repr) }
}
}

/// Create a [`Repr`] with the provided `capacity`
Expand Down
4 changes: 2 additions & 2 deletions compact_str/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,7 @@ fn test_truncate_noops_if_new_len_greater_than_current_static_str() {
short.truncate(100);

assert_eq!(short.len(), 5);
assert_eq!(short.capacity(), 5);
assert_eq!(short.capacity(), MAX_SIZE);

let mut long =
CompactString::from_static_str("i am a long string that will be allocated on the heap");
Expand Down Expand Up @@ -1541,7 +1541,7 @@ fn test_reserve_shrink_roundtrip_static_inline() {

let mut s = CompactString::from_static_str(TEXT);
assert!(!s.is_heap_allocated());
assert_eq!(s.capacity(), TEXT.len());
assert_eq!(s.capacity(), MAX_SIZE);
assert_eq!(s, TEXT);

s.reserve(128);
Expand Down

0 comments on commit f1e0649

Please sign in to comment.