diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-13 13:04:45 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-13 13:04:45 +0000 |
commit | fe4a94fff379e69acf31bf4c8b0d2490107a2dae (patch) | |
tree | 65f614b2c839379c294f4ea08564d135f5b7ad4c /crates/mbe/src/expander/transcriber.rs | |
parent | 88f78bdb9b64e0ba4ca5924599e42a524f5c3b64 (diff) | |
parent | 9117148f42371108f49de84ff765da987dcb5917 (diff) |
Merge #7994
7994: Speed up mbe matching in heavy recursive cases r=edwin0cheng a=edwin0cheng
In some cases (e.g. #4186), mbe matching is very slow due to a lot of copy and allocation for bindings, this PR try to solve this problem by introduce a semi "link-list" approach for bindings building.
I used this [test case](https://github.com/weiznich/minimal_example_for_rust_81262) (for `features(32-column-tables)`) to run following command to benchmark:
```
time rust-analyzer analysis-stats --load-output-dirs ./
```
Before this PR : 2 mins
After this PR: 3 seconds.
However, for 64-column-tables cases, we still need 4 mins to complete.
I will try to investigate in the following weeks.
bors r+
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/mbe/src/expander/transcriber.rs')
-rw-r--r-- | crates/mbe/src/expander/transcriber.rs | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/crates/mbe/src/expander/transcriber.rs b/crates/mbe/src/expander/transcriber.rs index ad9953a7d..c679e5e5d 100644 --- a/crates/mbe/src/expander/transcriber.rs +++ b/crates/mbe/src/expander/transcriber.rs | |||
@@ -13,17 +13,13 @@ use crate::{ | |||
13 | 13 | ||
14 | impl Bindings { | 14 | impl Bindings { |
15 | fn contains(&self, name: &str) -> bool { | 15 | fn contains(&self, name: &str) -> bool { |
16 | self.inner.iter().any(|(n, _)| n == name) | 16 | self.inner.contains_key(name) |
17 | } | 17 | } |
18 | 18 | ||
19 | fn get(&self, name: &str, nesting: &mut [NestingState]) -> Result<&Fragment, ExpandError> { | 19 | fn get(&self, name: &str, nesting: &mut [NestingState]) -> Result<&Fragment, ExpandError> { |
20 | let mut b: &Binding = self | 20 | let mut b: &Binding = self.inner.get(name).ok_or_else(|| { |
21 | .inner | 21 | ExpandError::BindingError(format!("could not find binding `{}`", name)) |
22 | .iter() | 22 | })?; |
23 | .find_map(|(n, b)| if n == name { Some(b) } else { None }) | ||
24 | .ok_or_else(|| { | ||
25 | ExpandError::BindingError(format!("could not find binding `{}`", name)) | ||
26 | })?; | ||
27 | for nesting_state in nesting.iter_mut() { | 23 | for nesting_state in nesting.iter_mut() { |
28 | nesting_state.hit = true; | 24 | nesting_state.hit = true; |
29 | b = match b { | 25 | b = match b { |