about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyan Lopopolo <rjl@hyperbo.la>2021-02-16 14:14:59 -0800
committerRyan Lopopolo <rjl@hyperbo.la>2021-02-16 14:20:26 -0800
commit2fcb8b5c201d22060f1ba46cc2291cacca593e02 (patch)
treeda76fa4d1e9014c9873227df0283e2efee7ba6e8
parent3ed618443437307749e4c773f260c2b4b94673f5 (diff)
downloadrust-2fcb8b5c201d22060f1ba46cc2291cacca593e02.tar.gz
rust-2fcb8b5c201d22060f1ba46cc2291cacca593e02.zip
Optimize FromIterator<OsString> to reuse the first allocation
-rw-r--r--library/std/src/ffi/os_str.rs15
1 files changed, 11 insertions, 4 deletions
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index b7aff83eaf5..8240aafae74 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -1208,11 +1208,18 @@ impl<'a> Extend<&'a OsStr> for OsString {
 impl FromIterator<OsString> for OsString {
     #[inline]
     fn from_iter<I: IntoIterator<Item = OsString>>(iter: I) -> Self {
-        let mut buf = Self::new();
-        for s in iter {
-            buf.push(&s);
+        let mut iterator = iter.into_iter();
+
+        // Because we're iterating over `OsString`s, we can avoid at least
+        // one allocation by getting the first string from the iterator
+        // and appending to it all the subsequent strings.
+        match iterator.next() {
+            None => OsString::new(),
+            Some(mut buf) => {
+                buf.extend(iterator);
+                buf
+            }
         }
-        buf
     }
 }