Skip to content

Commit

Permalink
perf(es/lexer): Make lexing of string literals faster (#9077)
Browse files Browse the repository at this point in the history
**Description:**

We don't need to push a character at a time. This profiling result does not include improvements from
#9076.

```
Benchmarking es/lexer/cal-com
es/lexer/cal-com        time:   [6.4555 ms 6.4936 ms 6.5368 ms]
```
  • Loading branch information
kdy1 authored Jun 18, 2024
1 parent c0d40c6 commit 373bac5
Showing 1 changed file with 83 additions and 26 deletions.
109 changes: 83 additions & 26 deletions crates/swc_ecma_parser/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,24 +969,42 @@ impl<'a> Lexer<'a> {
fn read_str_lit(&mut self) -> LexResult<Token> {
debug_assert!(self.cur() == Some('\'') || self.cur() == Some('"'));
let start = self.cur_pos();
let quote = self.cur().unwrap();
let quote = self.cur().unwrap() as u8;

self.bump(); // '"'

self.with_buf(|l, out| {
while let Some(c) = {
// Optimization
{
let s = l
.input
.uncons_while(|c| c != quote && c != '\\' && !c.is_line_break());
out.push_str(s);
}
l.cur()
} {
match c {
c if c == quote => {
l.bump();
let mut has_escape = false;
let mut slice_start = self.input.cur_pos();

self.with_buf(|l, buf| {
loop {
if let Some(c) = l.input.cur_as_ascii() {
if c == quote {
let value_end = l.cur_pos();

let value = if !has_escape {
let s = unsafe {
// Safety: slice_start and value_end are valid position because we
// got them from `self.input`
l.input.slice(slice_start, value_end)
};

l.atoms.atom(s)
} else {
let s = unsafe {
// Safety: slice_start and value_end are valid position because we
// got them from `self.input`
l.input.slice(slice_start, value_end)
};
buf.push_str(s);

l.atoms.atom(&**buf)
};

unsafe {
// Safety: cur is quote
l.input.bump();
}

let end = l.cur_pos();

Expand All @@ -995,28 +1013,67 @@ impl<'a> Lexer<'a> {
// `self.input`
l.input.slice(start, end)
};
let raw = l.atoms.atom(raw);

return Ok(Token::Str {
value: l.atoms.atom(&*out),
raw: l.atoms.atom(raw),
});
return Ok(Token::Str { value, raw });
}
'\\' => {

if c == b'\\' {
has_escape = true;

{
let end = l.cur_pos();
let s = unsafe {
// Safety: start and end are valid position because we got them from
// `self.input`
l.input.slice(slice_start, end)
};
buf.push_str(s);
}

if let Some(chars) = l.read_escaped_char(false)? {
for c in chars {
out.extend(c);
buf.extend(c);
}
}

slice_start = l.cur_pos();
continue;
}
c if c.is_line_break() => {

if (c as char).is_line_break() {
break;
}
_ => {
out.push(c);

l.bump();
unsafe {
// Safety: cur is a ascii character
l.input.bump();
}
continue;
}

match l.input.cur() {
Some(c) => {
if c.is_line_break() {
break;
}
unsafe {
// Safety: cur is Some(c)
l.input.bump();
}
}
None => break,
}
}

{
let end = l.cur_pos();
let s = unsafe {
// Safety: start and end are valid position because we got them from
// `self.input`
l.input.slice(slice_start, end)
};
buf.push_str(s);
}

l.emit_error(start, SyntaxError::UnterminatedStrLit);
Expand All @@ -1029,7 +1086,7 @@ impl<'a> Lexer<'a> {
l.input.slice(start, end)
};
Ok(Token::Str {
value: l.atoms.atom(&*out),
value: l.atoms.atom(&*buf),
raw: l.atoms.atom(raw),
})
})
Expand Down

1 comment on commit 373bac5

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 373bac5 Previous: 6426928 Ratio
es/full/bugs-1 273315 ns/iter (± 13666) 297024 ns/iter (± 6679) 0.92
es/full/minify/libraries/antd 1875331502 ns/iter (± 48111854) 2042491599 ns/iter (± 38561340) 0.92
es/full/minify/libraries/d3 354431576 ns/iter (± 4487176) 399571106 ns/iter (± 5078299) 0.89
es/full/minify/libraries/echarts 1587068452 ns/iter (± 24860863) 1734434572 ns/iter (± 15325791) 0.92
es/full/minify/libraries/jquery 104756977 ns/iter (± 596776) 106245144 ns/iter (± 1223850) 0.99
es/full/minify/libraries/lodash 116361001 ns/iter (± 863675) 117047242 ns/iter (± 883997) 0.99
es/full/minify/libraries/moment 60229654 ns/iter (± 197422) 60489422 ns/iter (± 285608) 1.00
es/full/minify/libraries/react 18514501 ns/iter (± 68139) 18538061 ns/iter (± 62908) 1.00
es/full/minify/libraries/terser 294793222 ns/iter (± 5755381) 304982350 ns/iter (± 2473360) 0.97
es/full/minify/libraries/three 500099343 ns/iter (± 6031104) 552215413 ns/iter (± 7244349) 0.91
es/full/minify/libraries/typescript 3283670699 ns/iter (± 38211593) 3436816600 ns/iter (± 37297033) 0.96
es/full/minify/libraries/victory 800527265 ns/iter (± 30158638) 947376612 ns/iter (± 18884928) 0.84
es/full/minify/libraries/vue 149154830 ns/iter (± 778973) 150922506 ns/iter (± 1553895) 0.99
es/full/codegen/es3 59670 ns/iter (± 464) 59721 ns/iter (± 127) 1.00
es/full/codegen/es5 59701 ns/iter (± 170) 60408 ns/iter (± 415) 0.99
es/full/codegen/es2015 59838 ns/iter (± 132) 59830 ns/iter (± 364) 1.00
es/full/codegen/es2016 59775 ns/iter (± 916) 59690 ns/iter (± 154) 1.00
es/full/codegen/es2017 59755 ns/iter (± 151) 59707 ns/iter (± 120) 1.00
es/full/codegen/es2018 60325 ns/iter (± 442) 59615 ns/iter (± 80) 1.01
es/full/codegen/es2019 60214 ns/iter (± 360) 59724 ns/iter (± 90) 1.01
es/full/codegen/es2020 60755 ns/iter (± 232) 59536 ns/iter (± 183) 1.02
es/full/all/es3 162322991 ns/iter (± 912394) 165812330 ns/iter (± 1797687) 0.98
es/full/all/es5 156882552 ns/iter (± 1064118) 160719582 ns/iter (± 820091) 0.98
es/full/all/es2015 116576381 ns/iter (± 794122) 118681865 ns/iter (± 880279) 0.98
es/full/all/es2016 115321560 ns/iter (± 722814) 116768359 ns/iter (± 586376) 0.99
es/full/all/es2017 115480182 ns/iter (± 752673) 116329269 ns/iter (± 737134) 0.99
es/full/all/es2018 112385488 ns/iter (± 634677) 114434726 ns/iter (± 730841) 0.98
es/full/all/es2019 111802739 ns/iter (± 517531) 114966667 ns/iter (± 758900) 0.97
es/full/all/es2020 108225624 ns/iter (± 723372) 109703594 ns/iter (± 841774) 0.99
es/full/parser 466283 ns/iter (± 2069) 484361 ns/iter (± 5510) 0.96
es/full/base/fixer 16208 ns/iter (± 196) 15163 ns/iter (± 69) 1.07
es/full/base/resolver_and_hygiene 81098 ns/iter (± 146) 78937 ns/iter (± 241) 1.03
serialization of serde 276 ns/iter (± 6) 278 ns/iter (± 9) 0.99
css/minify/libraries/bootstrap 22377661 ns/iter (± 166018) 21893721 ns/iter (± 250957) 1.02
css/visitor/compare/clone 1398601 ns/iter (± 18530) 1397438 ns/iter (± 10792) 1.00
css/visitor/compare/visit_mut_span 1535754 ns/iter (± 20597) 1518919 ns/iter (± 7985) 1.01
css/visitor/compare/visit_mut_span_panic 1542691 ns/iter (± 29365) 1536625 ns/iter (± 19884) 1.00
css/visitor/compare/fold_span 2036408 ns/iter (± 11176) 2062027 ns/iter (± 5090) 0.99
css/visitor/compare/fold_span_panic 2163000 ns/iter (± 34252) 2172400 ns/iter (± 4738) 1.00
css/lexer/bootstrap_5_1_3 3442449 ns/iter (± 47200) 3401658 ns/iter (± 14751) 1.01
css/lexer/foundation_6_7_4 2792809 ns/iter (± 7793) 2757338 ns/iter (± 5598) 1.01
css/lexer/tailwind_3_1_1 532626 ns/iter (± 28963) 526137 ns/iter (± 322) 1.01
css/parser/bootstrap_5_1_3 16221265 ns/iter (± 107573) 16163314 ns/iter (± 45578) 1.00
css/parser/foundation_6_7_4 13040985 ns/iter (± 195431) 12885701 ns/iter (± 222570) 1.01
css/parser/tailwind_3_1_1 2533231 ns/iter (± 38561) 2557413 ns/iter (± 5409) 0.99
es/codegen/colors 729550 ns/iter (± 402946) 708556 ns/iter (± 390355) 1.03
es/codegen/large 3055805 ns/iter (± 1614404) 2994189 ns/iter (± 1603183) 1.02
es/codegen/with-parser/colors 42045 ns/iter (± 222) 41699 ns/iter (± 455) 1.01
es/codegen/with-parser/large 455895 ns/iter (± 3960) 454473 ns/iter (± 1961) 1.00
es/minify/libraries/antd 1438903021 ns/iter (± 31497960) 1660150750 ns/iter (± 41553547) 0.87
es/minify/libraries/d3 282781904 ns/iter (± 5193951) 358788890 ns/iter (± 9621500) 0.79
es/minify/libraries/echarts 1161394999 ns/iter (± 15118643) 1385004459 ns/iter (± 14609561) 0.84
es/minify/libraries/jquery 82594751 ns/iter (± 220033) 93671740 ns/iter (± 1711064) 0.88
es/minify/libraries/lodash 104361795 ns/iter (± 366858) 110726655 ns/iter (± 1081675) 0.94
es/minify/libraries/moment 48132569 ns/iter (± 125636) 50175406 ns/iter (± 186715) 0.96
es/minify/libraries/react 16168719 ns/iter (± 15812) 16978034 ns/iter (± 50489) 0.95
es/minify/libraries/terser 217384124 ns/iter (± 279040) 270567467 ns/iter (± 4070915) 0.80
es/minify/libraries/three 362936763 ns/iter (± 1070722) 474270540 ns/iter (± 4942209) 0.77
es/minify/libraries/typescript 2709351465 ns/iter (± 25866724) 2927273049 ns/iter (± 26912059) 0.93
es/minify/libraries/victory 577062492 ns/iter (± 10963378) 710420356 ns/iter (± 16964886) 0.81
es/minify/libraries/vue 121019079 ns/iter (± 363143) 122790668 ns/iter (± 711362) 0.99
es/visitor/compare/clone 1716597 ns/iter (± 24197) 1683744 ns/iter (± 6686) 1.02
es/visitor/compare/visit_mut_span 2066102 ns/iter (± 30572) 2020696 ns/iter (± 9239) 1.02
es/visitor/compare/visit_mut_span_panic 2050179 ns/iter (± 71382) 2016470 ns/iter (± 20993) 1.02
es/visitor/compare/fold_span 2768895 ns/iter (± 10236) 2727865 ns/iter (± 5929) 1.02
es/visitor/compare/fold_span_panic 2802691 ns/iter (± 6067) 2763366 ns/iter (± 3169) 1.01
es/lexer/colors 9779 ns/iter (± 85) 9777 ns/iter (± 26) 1.00
es/lexer/angular 5245044 ns/iter (± 23059) 5117679 ns/iter (± 23055) 1.02
es/lexer/backbone 637692 ns/iter (± 3779) 660840 ns/iter (± 2682) 0.96
es/lexer/jquery 3718545 ns/iter (± 26902) 3566791 ns/iter (± 3809) 1.04
es/lexer/jquery mobile 5652660 ns/iter (± 7681) 5345639 ns/iter (± 14445) 1.06
es/lexer/mootools 2860997 ns/iter (± 1648) 2875128 ns/iter (± 21553) 1.00
es/lexer/underscore 538161 ns/iter (± 613) 532769 ns/iter (± 602) 1.01
es/lexer/three 16259224 ns/iter (± 69600) 16331780 ns/iter (± 94428) 1.00
es/lexer/yui 2989888 ns/iter (± 12024) 2970361 ns/iter (± 3873) 1.01
es/lexer/cal-com 12826096 ns/iter (± 17368) 12982352 ns/iter (± 43846) 0.99
es/lexer/typescript 90786058 ns/iter (± 447925) 90949731 ns/iter (± 447483) 1.00
es/parser/colors 24644 ns/iter (± 77) 24580 ns/iter (± 124) 1.00
es/parser/angular 12476036 ns/iter (± 56728) 12424789 ns/iter (± 147560) 1.00
es/parser/backbone 1843279 ns/iter (± 11856) 1835741 ns/iter (± 8000) 1.00
es/parser/jquery 10111584 ns/iter (± 77560) 10093791 ns/iter (± 160507) 1.00
es/parser/jquery mobile 15323886 ns/iter (± 83830) 15268349 ns/iter (± 97897) 1.00
es/parser/mootools 7907871 ns/iter (± 31436) 7846791 ns/iter (± 14183) 1.01
es/parser/underscore 1608133 ns/iter (± 4608) 1594569 ns/iter (± 8927) 1.01
es/parser/three 44386499 ns/iter (± 667571) 43655555 ns/iter (± 294234) 1.02
es/parser/yui 7465653 ns/iter (± 38237) 7496580 ns/iter (± 45866) 1.00
es/parser/cal-com 39841493 ns/iter (± 141524) 39928200 ns/iter (± 260500) 1.00
es/parser/typescript 267590754 ns/iter (± 867934) 269758547 ns/iter (± 1236592) 0.99
es/preset-env/usage/builtin_type 135913 ns/iter (± 34839) 136454 ns/iter (± 34767) 1.00
es/preset-env/usage/property 16532 ns/iter (± 57) 16620 ns/iter (± 121) 0.99
es/resolver/typescript 102170531 ns/iter (± 3317082) 100034028 ns/iter (± 2698678) 1.02
es/fixer/typescript 81553860 ns/iter (± 3098715) 79478664 ns/iter (± 4749582) 1.03
es/hygiene/typescript 190743227 ns/iter (± 7231408) 184559918 ns/iter (± 5411647) 1.03
es/resolver_with_hygiene/typescript 310795961 ns/iter (± 3623176) 310996032 ns/iter (± 3411752) 1.00
es/visitor/base-perf/module_clone 58044 ns/iter (± 2045) 56763 ns/iter (± 912) 1.02
es/visitor/base-perf/fold_empty 61310 ns/iter (± 816) 60222 ns/iter (± 794) 1.02
es/visitor/base-perf/fold_noop_impl_all 61413 ns/iter (± 741) 60745 ns/iter (± 838) 1.01
es/visitor/base-perf/fold_noop_impl_vec 61898 ns/iter (± 1201) 60627 ns/iter (± 680) 1.02
es/visitor/base-perf/boxing_boxed_clone 60 ns/iter (± 1) 58 ns/iter (± 0) 1.03
es/visitor/base-perf/boxing_unboxed_clone 47 ns/iter (± 0) 47 ns/iter (± 0) 1
es/visitor/base-perf/boxing_boxed 105 ns/iter (± 0) 106 ns/iter (± 0) 0.99
es/visitor/base-perf/boxing_unboxed 80 ns/iter (± 0) 82 ns/iter (± 0) 0.98
es/visitor/base-perf/visit_contains_this 2527 ns/iter (± 23) 2462 ns/iter (± 19) 1.03
es/base/parallel/resolver/typescript 2307668317 ns/iter (± 148917439) 2422314327 ns/iter (± 106731532) 0.95
es/base/parallel/hygiene/typescript 3197996952 ns/iter (± 66385536) 3215614515 ns/iter (± 32862941) 0.99
babelify-only 475654 ns/iter (± 13969) 480027 ns/iter (± 5987) 0.99
parse_and_babelify_angular 42555573 ns/iter (± 1067590) 38738072 ns/iter (± 999683) 1.10
parse_and_babelify_backbone 4336189 ns/iter (± 24888) 4750652 ns/iter (± 190392) 0.91
parse_and_babelify_jquery 28397292 ns/iter (± 202083) 30361717 ns/iter (± 876596) 0.94
parse_and_babelify_jquery_mobile 48732674 ns/iter (± 668160) 49935560 ns/iter (± 879279) 0.98
parse_and_babelify_mootools 25478322 ns/iter (± 148549) 26698334 ns/iter (± 482395) 0.95
parse_and_babelify_underscore 3675846 ns/iter (± 15368) 3698352 ns/iter (± 39655) 0.99
parse_and_babelify_yui 23380429 ns/iter (± 218225) 24989030 ns/iter (± 909478) 0.94
html/minify/document/css_spec 46850237 ns/iter (± 533417) 45612799 ns/iter (± 474317) 1.03
html/minify/document/github 18562822 ns/iter (± 59242) 17858159 ns/iter (± 85105) 1.04
html/minify/document/stackoverflow 16952254 ns/iter (± 433898) 16248417 ns/iter (± 487811) 1.04
html/minify/document_fragment/css_spec 47979371 ns/iter (± 529780) 44263581 ns/iter (± 416858) 1.08
html/minify/document_fragment/github 18414403 ns/iter (± 78804) 17603939 ns/iter (± 18626) 1.05
html/minify/document_fragment/stackoverflow 16781322 ns/iter (± 49917) 16152566 ns/iter (± 86207) 1.04
html/document/visitor/compare/clone 167704 ns/iter (± 2485) 165725 ns/iter (± 1972) 1.01
html/document/visitor/compare/visit_mut_span 182054 ns/iter (± 1824) 182728 ns/iter (± 1500) 1.00
html/document/visitor/compare/visit_mut_span_panic 186077 ns/iter (± 4278) 187768 ns/iter (± 3108) 0.99
html/document/visitor/compare/fold_span 227959 ns/iter (± 1145) 228793 ns/iter (± 2647) 1.00
html/document/visitor/compare/fold_span_panic 280083 ns/iter (± 845) 276339 ns/iter (± 1660) 1.01
html/document_fragment/visitor/compare/clone 164404 ns/iter (± 1456) 165107 ns/iter (± 905) 1.00
html/document_fragment/visitor/compare/visit_mut_span 184777 ns/iter (± 1110) 183506 ns/iter (± 1365) 1.01
html/document_fragment/visitor/compare/visit_mut_span_panic 188851 ns/iter (± 1184) 185667 ns/iter (± 1371) 1.02
html/document_fragment/visitor/compare/fold_span 229400 ns/iter (± 1130) 229095 ns/iter (± 819) 1.00
html/document_fragment/visitor/compare/fold_span_panic 279645 ns/iter (± 1247) 277934 ns/iter (± 9473) 1.01
html/lexer/css_2021_spec 12948537 ns/iter (± 85065) 12949772 ns/iter (± 135368) 1.00
html/lexer/github_com_17_05_2022 4927845 ns/iter (± 6181) 4932298 ns/iter (± 70224) 1.00
html/lexer/stackoverflow_com_17_05_2022 4681862 ns/iter (± 15539) 4683889 ns/iter (± 3603) 1.00
html/parser/parser_document/css_2021_spec 25316715 ns/iter (± 80065) 26197956 ns/iter (± 351280) 0.97
html/parser/parser_document/github_com_17_05_2022 8528045 ns/iter (± 77810) 8628078 ns/iter (± 60969) 0.99
html/parser/parser_document/stackoverflow_com_17_05_2022 7461070 ns/iter (± 44005) 7463495 ns/iter (± 10622) 1.00
html/parser/parser_document_fragment/css_2021_spec 25174648 ns/iter (± 101167) 25300387 ns/iter (± 283278) 1.00
html/parser/parser_document_fragment/github_com_17_05_2022 8457509 ns/iter (± 35072) 8517107 ns/iter (± 71188) 0.99
html/parser/parser_document_fragment/stackoverflow_com_17_05_2022 7453820 ns/iter (± 7830) 7396567 ns/iter (± 38730) 1.01

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.