Adjust heuristics to better handle "{}..." format strings.
This commit is contained in:
parent
e74b55b9da
commit
7403ee9d07
2 changed files with 15 additions and 10 deletions
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue