diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 52ceb8b45f91c..67b2750d3756e 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -270,7 +270,6 @@ impl str { #[inline] pub fn replace(&self, from: P, to: &str) -> String { // Fast path for ASCII to ASCII case. - if let Some(from_byte) = match from.as_utf8_pattern() { Some(Utf8Pattern::StringPattern([from_byte])) => Some(*from_byte), Some(Utf8Pattern::CharPattern(c)) => c.as_ascii().map(|ascii_char| ascii_char.to_u8()), @@ -280,8 +279,16 @@ impl str { return unsafe { replace_ascii(self.as_bytes(), from_byte, *to_byte) }; } } - - let mut result = String::new(); + let to_len = to.as_bytes().len(); + // Set result capacity to self.len() when from.len() <= to.len() + let default_capacity = match from.as_utf8_pattern() { + Some(Utf8Pattern::StringPattern(s)) if s.len() <= to_len => self.len(), + Some(Utf8Pattern::CharPattern(c)) if c.encode_utf8(&mut [0; 4]).len() <= to_len => { + self.len() + } + _ => 0, + }; + let mut result = String::with_capacity(default_capacity); let mut last_end = 0; for (start, part) in self.match_indices(from) { result.push_str(unsafe { self.get_unchecked(last_end..start) });