about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2018-10-29 09:47:45 +0100
committerGitHub <noreply@github.com>2018-10-29 09:47:45 +0100
commit97ff2d6ab1bea79c7ff4ae60a8ab600ce8b82c8e (patch)
tree47402e0fc7d82c9fa26bffa7a69653b4ae770543 /src
parent4e88b7363b7858960ccfd87326ece9d00bf4d973 (diff)
parenteb637d26ba4652ea65ef58288af0697c32ebc503 (diff)
downloadrust-97ff2d6ab1bea79c7ff4ae60a8ab600ce8b82c8e.tar.gz
rust-97ff2d6ab1bea79c7ff4ae60a8ab600ce8b82c8e.zip
Rollup merge of #55384 - nnethercote:better-integer_lit-float_lit, r=michaelwoerister
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%.
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/parse/mod.rs23
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);