Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: Update From<String> and From<Box<str>> to eagerly inline #256

Merged
merged 3 commits into from
Feb 18, 2023

Conversation

ParkMyCar
Copy link
Owner

Currently when converting from a String to a CompactString using From<String> (also for Box<str>) we wouldn't inline short strings, this was to avoid needing to de-allocate the original String. After some feedback collected in #227 we realized while this was performant, it's not what most users expect to happen.

This PR updates the implementation of From<String> and From<Box<str>> to inline short strings, and it adds a new API CompactStr::from_string_buffer, which retains the current behavior of always re-using the underlying buffer. Note, in #254 we implemented inline-ing during Clone, so even if you use from_string_buffer, future short strings should get inlined.

Fixes #227

@@ -165,9 +166,14 @@ impl Repr {
// We only hit this case if the provided String is > 16MB and we're on a 32-bit arch. We
// expect it to be unlikely, thus we hint that to the compiler
capacity_on_heap(s)
} else if og_cap == 0 {
} else if s.is_empty() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If should_inline is false and s contains a large pre-allocated buffer, then should we re-use the buffer to avoid alloc?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good thought, I updated the PR to be based on capacity now instead of length

Reason being, when created a String will only allocate as much space as needed. When appending to a string though it grows at a rate of 2x to amortize the cost of re-allocations. This leaves us with 2 scenarios:

  1. capacity == length, in which case it doesn't matter which we check
  2. capacity > length, this indicates the user appended to the string, or specifically allocated more space, which it seems like we'd want to keep

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm, actually it seems like Clone-ing today actually doesn't preserve capacity, example, so my assumption that users would want to preserve capacity might be wrong, let me think more

@@ -232,7 +238,7 @@ impl Repr {
}

#[inline]
pub fn from_box_str(s: Box<str>) -> Self {
pub fn from_box_str(s: Box<str>, should_inline: bool) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this can be forwarded to Repr::from_string

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call! I made this change

- add doc comment to CompactString explaining the behavior of From<String>
- change Repr::from_string to eagerly inline based on string length, not capacity, which results in us possibly truncating capacity
- delete Repr::from_box_str, and have impl From<Box<str>> for CompactString use Repr::from_string
- update tests
@ParkMyCar ParkMyCar merged commit 146479e into main Feb 18, 2023
@ParkMyCar ParkMyCar deleted the api/from-string-from-boxstr branch February 18, 2023 00:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Should From<String> convert to inline if possible?
2 participants