diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2019-10-23 21:00:04 +0200 |
|---|---|---|
| committer | Mara Bos <m-ou.se@m-ou.se> | 2019-10-23 21:21:25 +0200 |
| commit | 18ae175d60039dfe2d2454e8e8099d3b08039862 (patch) | |
| tree | 068d7ce776db3662f0172ce79e7110c8692d40a6 /src/libstd/path.rs | |
| parent | 4a8c5b20c7772bc5342b83d4b0696ea216ef75a7 (diff) | |
| download | rust-18ae175d60039dfe2d2454e8e8099d3b08039862.tar.gz rust-18ae175d60039dfe2d2454e8e8099d3b08039862.zip | |
Prevent unnecessary allocation in PathBuf::set_extension.
It was allocating a new OsString that was immediately dropped after using it with set_file_name. Now it directly changes the extension in the original buffer, without touching the rest of the file name or allocating a temporary string.
Diffstat (limited to 'src/libstd/path.rs')
| -rw-r--r-- | src/libstd/path.rs | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/src/libstd/path.rs b/src/libstd/path.rs index ca81044ee85..6d6bc760649 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1363,20 +1363,24 @@ impl PathBuf { } fn _set_extension(&mut self, extension: &OsStr) -> bool { - if self.file_name().is_none() { - return false; - } - - let mut stem = match self.file_stem() { - Some(stem) => stem.to_os_string(), - None => OsString::new(), + let file_stem = match self.file_stem() { + None => return false, + Some(f) => os_str_as_u8_slice(f), }; - if !os_str_as_u8_slice(extension).is_empty() { - stem.push("."); - stem.push(extension); + // truncate until right after the file stem + let end_file_stem = file_stem[file_stem.len()..].as_ptr() as usize; + let start = os_str_as_u8_slice(&self.inner).as_ptr() as usize; + let v = self.as_mut_vec(); + v.truncate(end_file_stem.wrapping_sub(start)); + + // add the new extension, if any + let new = os_str_as_u8_slice(extension); + if !new.is_empty() { + v.reserve_exact(new.len() + 1); + v.push(b'.'); + v.extend_from_slice(new); } - self.set_file_name(&stem); true } |
