]> git.lizzy.rs Git - rust.git/commitdiff
Avoid realloc in `CString::new`
authorShotaro Yamada <sinkuu@sinkuu.xyz>
Fri, 18 Oct 2019 07:10:13 +0000 (16:10 +0900)
committerShotaro Yamada <sinkuu@sinkuu.xyz>
Fri, 18 Oct 2019 07:10:13 +0000 (16:10 +0900)
src/librustc_codegen_llvm/back/lto.rs
src/libstd/ffi/c_str.rs
src/libstd/lib.rs

index 7437b1e3c8a32e2f7c31599d57a117fd86015de7..b3be3d09f17da9c06748786d74244af39edfcffb 100644 (file)
@@ -53,9 +53,7 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
 
     let symbol_filter = &|&(ref name, level): &(String, SymbolExportLevel)| {
         if level.is_below_threshold(export_threshold) {
-            let mut bytes = Vec::with_capacity(name.len() + 1);
-            bytes.extend(name.bytes());
-            Some(CString::new(bytes).unwrap())
+            Some(CString::new(name.as_str()).unwrap())
         } else {
             None
         }
index 483f2ba52eca658c5516f27a7e0adab2213d96ef..6dcda98631014a1eed927bdcc5c5c7c73af702a7 100644 (file)
@@ -327,7 +327,31 @@ impl CString {
     /// [`NulError`]: struct.NulError.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
-        Self::_new(t.into())
+        trait SpecIntoVec {
+            fn into_vec(self) -> Vec<u8>;
+        }
+        impl<T: Into<Vec<u8>>> SpecIntoVec for T {
+            default fn into_vec(self) -> Vec<u8> {
+                self.into()
+            }
+        }
+        // Specialization for avoiding reallocation.
+        impl SpecIntoVec for &'_ [u8] {
+            fn into_vec(self) -> Vec<u8> {
+                let mut v = Vec::with_capacity(self.len() + 1);
+                v.extend(self);
+                v
+            }
+        }
+        impl SpecIntoVec for &'_ str {
+            fn into_vec(self) -> Vec<u8> {
+                let mut v = Vec::with_capacity(self.len() + 1);
+                v.extend(self.as_bytes());
+                v
+            }
+        }
+
+        Self::_new(SpecIntoVec::into_vec(t))
     }
 
     fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
index af6cb656444d425fb2805f247f35c60e521373fe..50a1226cc1d07be54ff7ab68d27310bd6a3763e5 100644 (file)
 #![feature(slice_concat_ext)]
 #![feature(slice_internals)]
 #![feature(slice_patterns)]
+#![feature(specialization)]
 #![feature(staged_api)]
 #![feature(std_internals)]
 #![feature(stdsimd)]