diff options
| author | kennytm <kennytm@gmail.com> | 2018-05-09 17:23:31 +0800 |
|---|---|---|
| committer | kennytm <kennytm@gmail.com> | 2018-05-09 17:23:31 +0800 |
| commit | 0fa08507efe4187a8056691ceb550e9da1171863 (patch) | |
| tree | 6b8260d2cf192a4fa0fad7967d867f974a7c8d91 /src/libsyntax/parse | |
| parent | e6a309e352e10a4758a911f7ea7d2cdfd24943c3 (diff) | |
| parent | 65ea0ff29d32ca4fea30477f7fb1a1d43342dc26 (diff) | |
| download | rust-0fa08507efe4187a8056691ceb550e9da1171863.tar.gz rust-0fa08507efe4187a8056691ceb550e9da1171863.zip | |
Rollup merge of #50525 - nnethercote:lit_token, r=michaelwoerister
Optimize string handling in lit_token().
In the common case, the string value in a string literal Token is the
same as the string value in a string literal LitKind. (The exception is
when escapes or \r are involved.) This patch takes advantage of that to
avoid calling str_lit() and re-interning the string in that case. This
speeds up incremental builds for a few of the rustc-benchmarks, the best
by 3%.
Benchmarks that got a speedup of 1% or more:
```
coercions
avg: -1.1% min: -3.5% max: 0.4%
regex-check
avg: -1.2% min: -1.5% max: -0.6%
futures-check
avg: -0.9% min: -1.4% max: -0.3%
futures
avg: -0.8% min: -1.3% max: -0.3%
futures-opt
avg: -0.7% min: -1.2% max: -0.1%
regex
avg: -0.5% min: -1.2% max: -0.1%
regex-opt
avg: -0.5% min: -1.1% max: -0.1%
hyper-check
avg: -0.7% min: -1.0% max: -0.3%
```
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index f252020bc31..f26a6a53074 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -419,13 +419,24 @@ pub fn lit_token(lit: token::Lit, suf: Option<Symbol>, diag: Option<(Span, &Hand token::Integer(s) => (false, integer_lit(&s.as_str(), suf, diag)), token::Float(s) => (false, float_lit(&s.as_str(), suf, diag)), - token::Str_(s) => { - let s = Symbol::intern(&str_lit(&s.as_str(), diag)); - (true, Some(LitKind::Str(s, ast::StrStyle::Cooked))) + token::Str_(mut sym) => { + // If there are no characters requiring special treatment we can + // reuse the symbol from the Token. Otherwise, we must generate a + // new symbol because the string in the LitKind is different to the + // string in the Token. + let s = &sym.as_str(); + if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') { + sym = Symbol::intern(&str_lit(s, diag)); + } + (true, Some(LitKind::Str(sym, ast::StrStyle::Cooked))) } - token::StrRaw(s, n) => { - let s = Symbol::intern(&raw_str_lit(&s.as_str())); - (true, Some(LitKind::Str(s, ast::StrStyle::Raw(n)))) + token::StrRaw(mut sym, n) => { + // Ditto. + let s = &sym.as_str(); + if s.contains('\r') { + sym = Symbol::intern(&raw_str_lit(s)); + } + (true, Some(LitKind::Str(sym, ast::StrStyle::Raw(n)))) } token::ByteStr(i) => { (true, Some(LitKind::ByteStr(byte_str_lit(&i.as_str())))) |
