diff options
| author | Nicholas Nethercote <nnethercote@mozilla.com> | 2018-10-26 22:06:59 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <nnethercote@mozilla.com> | 2018-10-26 22:08:39 +1100 |
| commit | eb637d26ba4652ea65ef58288af0697c32ebc503 (patch) | |
| tree | 9e1aa216e2474f3d8f4f6d7c9993b0336b9eb2b2 | |
| parent | f99911a4a0bead7dd1f9ef2f90442844434cc391 (diff) | |
| download | rust-eb637d26ba4652ea65ef58288af0697c32ebc503.tar.gz rust-eb637d26ba4652ea65ef58288af0697c32ebc503.zip | |
Avoid unnecessary allocations in `float_lit` and `integer_lit`.
This commit avoids an allocation when parsing any float and integer literals that don't involved underscores. This reduces the number of allocations done for the `tuple-stress` benchmark by 10%, reducing its instruction count by just under 1%.
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index a4b8ab86f37..77a2ae6acf0 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -494,8 +494,17 @@ fn float_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>) -> Option<ast::LitKind> { debug!("float_lit: {:?}, {:?}", s, suffix); // FIXME #2252: bounds checking float literals is deferred until trans - let s = s.chars().filter(|&c| c != '_').collect::<String>(); - filtered_float_lit(Symbol::intern(&s), suffix, diag) + + // Strip underscores without allocating a new String unless necessary. + let s2; + let s = if s.chars().any(|c| c == '_') { + s2 = s.chars().filter(|&c| c != '_').collect::<String>(); + &s2 + } else { + s + }; + + filtered_float_lit(Symbol::intern(s), suffix, diag) } /// Parse a string representing a byte literal into its final form. Similar to `char_lit` @@ -591,8 +600,14 @@ fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>) -> Option<ast::LitKind> { // s can only be ascii, byte indexing is fine - let s2 = s.chars().filter(|&c| c != '_').collect::<String>(); - let mut s = &s2[..]; + // Strip underscores without allocating a new String unless necessary. + let s2; + let mut s = if s.chars().any(|c| c == '_') { + s2 = s.chars().filter(|&c| c != '_').collect::<String>(); + &s2 + } else { + s + }; debug!("integer_lit: {}, {:?}", s, suffix); |
