]> git.lizzy.rs Git - rust.git/commitdiff
cstring: avoid excessive growth just to 0-terminate
authorUlrik Sverdrup <bluss@users.noreply.github.com>
Sun, 21 Aug 2016 11:33:28 +0000 (13:33 +0200)
committerUlrik Sverdrup <bluss@users.noreply.github.com>
Sun, 21 Aug 2016 11:37:33 +0000 (13:37 +0200)
Based on following what happens in CString::new("string literal"):

1. Using `Into<Vec<u8>>`, a Vec is allocated with capacity exactly equal
   to the string's input length.
2. By `v.push(0)`, the Vec is grown to twice capacity, since it was full.
3. By `v.into_boxed_slice()`, the Vec capacity is shrunk to fit the length again.

If we use `.reserve_exact(1)` just before the push, then we avoid the
capacity doubling that we're going to have to shrink anyway.

Growing by just 1 byte means that the step (2) is less likely to have to
move the memory to a larger allocation chunk, and that the step (3) does
not have to reallocate.

src/libstd/ffi/c_str.rs

index 77b90c0846bbe44f2349b7a674223d6f47ea59f9..6f217be31fe678e513fbf5a3ac95a9b5d1b1cd1a 100644 (file)
@@ -213,6 +213,7 @@ fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {
     /// byte vector, not anything that can be converted to one with Into.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
+        v.reserve_exact(1);
         v.push(0);
         CString { inner: v.into_boxed_slice() }
     }