about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichał Krasnoborski <mkrdln@gmail.com>2017-02-01 23:47:03 +0100
committerMichał Krasnoborski <mkrdln@gmail.com>2017-02-01 23:47:03 +0100
commit7403ee9d07a1b096e9628871bd97e39f464c3aa5 (patch)
tree4863c5d592d5f3843f69431fb49342339ceb2c8d
parente74b55b9da5a163e02bbcbf97e7ea24d48742943 (diff)
downloadrust-7403ee9d07a1b096e9628871bd97e39f464c3aa5.tar.gz
rust-7403ee9d07a1b096e9628871bd97e39f464c3aa5.zip
Adjust heuristics to better handle "{}..." format strings.
-rw-r--r--src/libcore/fmt/mod.rs21
-rw-r--r--src/libcoretest/fmt/mod.rs4
2 files changed, 15 insertions, 10 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index ed9c5d3337f..a870b6f88fb 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -281,17 +281,20 @@ impl<'a> Arguments<'a> {
         let pieces_length: W<usize> = self.pieces.iter()
             .map(|x| W(x.len())).sum();
 
-        // If they are any arguments to format, the string will most likely
-        // double in size. So we're pre-doubling it here.
-        let multiplier = if self.args.is_empty() { W(1) } else { W(2) };
-
-        let capacity = multiplier * pieces_length;
-        if multiplier == W(2) && (W(1)..W(8)).contains(capacity) {
-            // Allocations smaller than 8 don't really make sense for String.
-            8
+        if self.args.is_empty() {
+            pieces_length.0
+        } else if self.pieces[0] == "" && pieces_length < W(16) {
+            // If the format string starts with an argument,
+            // don't preallocate anything, unless length
+            // of pieces is significant.
+            0
         } else {
-            capacity.0
+            // There are some arguments, so any additional push
+            // will reallocate the string. To avoid that,
+            // we're "pre-doubling" the capacity here.
+            (pieces_length * W(2)).0
         }
+
     }
 }
 
diff --git a/src/libcoretest/fmt/mod.rs b/src/libcoretest/fmt/mod.rs
index 71b3a440f7b..5d204c7d523 100644
--- a/src/libcoretest/fmt/mod.rs
+++ b/src/libcoretest/fmt/mod.rs
@@ -31,8 +31,10 @@ fn test_pointer_formats_data_pointer() {
 
 #[test]
 fn test_estimated_capacity() {
+    assert_eq!(format_args!("").estimated_capacity(), 0);
     assert_eq!(format_args!("{}", "").estimated_capacity(), 0);
     assert_eq!(format_args!("Hello").estimated_capacity(), 5);
     assert_eq!(format_args!("Hello, {}!", "").estimated_capacity(), 16);
-    assert_eq!(format_args!("{}, hello!", "World").estimated_capacity(), 16);
+    assert_eq!(format_args!("{}, hello!", "World").estimated_capacity(), 0);
+    assert_eq!(format_args!("{}. 16-bytes piece", "World").estimated_capacity(), 32);
 }