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/tt | |
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/tt')
-rw-r--r-- | crates/tt/src/lib.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs index 8301dc28a..9d9a01e30 100644 --- a/crates/tt/src/lib.rs +++ b/crates/tt/src/lib.rs | |||
@@ -227,6 +227,53 @@ impl Subtree { | |||
227 | } | 227 | } |
228 | } | 228 | } |
229 | 229 | ||
230 | impl Subtree { | ||
231 | /// A simple line string used for debugging | ||
232 | pub fn as_debug_string(&self) -> String { | ||
233 | let delim = match self.delimiter_kind() { | ||
234 | Some(DelimiterKind::Brace) => ("{", "}"), | ||
235 | Some(DelimiterKind::Bracket) => ("[", "]"), | ||
236 | Some(DelimiterKind::Parenthesis) => ("(", ")"), | ||
237 | None => (" ", " "), | ||
238 | }; | ||
239 | |||
240 | let mut res = String::new(); | ||
241 | res.push_str(delim.0); | ||
242 | let mut iter = self.token_trees.iter(); | ||
243 | let mut last = None; | ||
244 | while let Some(child) = iter.next() { | ||
245 | let s = match child { | ||
246 | TokenTree::Leaf(it) => { | ||
247 | let s = match it { | ||
248 | Leaf::Literal(it) => it.text.to_string(), | ||
249 | Leaf::Punct(it) => it.char.to_string(), | ||
250 | Leaf::Ident(it) => it.text.to_string(), | ||
251 | }; | ||
252 | match (it, last) { | ||
253 | (Leaf::Ident(_), Some(&TokenTree::Leaf(Leaf::Ident(_)))) => { | ||
254 | " ".to_string() + &s | ||
255 | } | ||
256 | (Leaf::Punct(_), Some(&TokenTree::Leaf(Leaf::Punct(punct)))) => { | ||
257 | if punct.spacing == Spacing::Alone { | ||
258 | " ".to_string() + &s | ||
259 | } else { | ||
260 | s | ||
261 | } | ||
262 | } | ||
263 | _ => s, | ||
264 | } | ||
265 | } | ||
266 | TokenTree::Subtree(it) => it.as_debug_string(), | ||
267 | }; | ||
268 | res.push_str(&s); | ||
269 | last = Some(child); | ||
270 | } | ||
271 | |||
272 | res.push_str(delim.1); | ||
273 | res | ||
274 | } | ||
275 | } | ||
276 | |||
230 | pub mod buffer; | 277 | pub mod buffer; |
231 | 278 | ||
232 | #[derive(Debug, PartialEq, Eq, Clone)] | 279 | #[derive(Debug, PartialEq, Eq, Clone)] |