From eb637d26ba4652ea65ef58288af0697c32ebc503 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 26 Oct 2018 22:06:59 +1100 Subject: [PATCH] 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%. --- src/libsyntax/parse/mod.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index a4b8ab86f37f6..77a2ae6acf00b 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -494,8 +494,17 @@ fn float_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler)>) -> Option { debug!("float_lit: {:?}, {:?}", s, suffix); // FIXME #2252: bounds checking float literals is deferred until trans - let s = s.chars().filter(|&c| c != '_').collect::(); - 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::(); + &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, diag: Option<(Span, &Handler)>) -> Option { // s can only be ascii, byte indexing is fine - let s2 = s.chars().filter(|&c| c != '_').collect::(); - 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::(); + &s2 + } else { + s + }; debug!("integer_lit: {}, {:?}", s, suffix);