Commit Graph

10 Commits

Author SHA1 Message Date
Lukas Wirth
cb6703fe06 internal: Don't parse files unnecessarily in scope_for_offset 2022-07-23 00:50:59 +02:00
Lukas Wirth
531e152390 fix: Simplify macro statement expansion handling 2022-07-01 14:49:30 +02:00
Ariel Davis
d4262f4af8 Migrate to SyntaxNodePtr in new rowan 2021-12-29 23:48:53 -08:00
Aramis Razzaghipour
55c0b86cde
Add semicolons for consistency
`clippy::semicolon_if_nothing_returned`
2021-10-03 23:39:43 +11:00
bors[bot]
e2ca2325f5
Merge #9367
9367: Document perf characteristic of to_node r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2021-06-22 08:46:01 +00:00
Aleksey Kladov
e611c6758c Document perf characteristic of to_node 2021-06-22 11:45:22 +03:00
Aleksey Kladov
099b63e7c0 feature: massively improve performance for large files
This story begins in #8384, where we added a smart test for our syntax
highting, which run the algorithm on synthetic files of varying length
in order to guesstimate if the complexity is O(N^2) or O(N)-ish.

The test turned out to be pretty effective, and flagged #9031 as a
change that makes syntax highlighting accidentally quadratic. There was
much rejoicing, for the time being.

Then, lnicola asked an ominous question[1]: "Are we sure that the time
is linear right now?"

Of course it turned out that our sophisticated non-linearity detector
*was* broken, and that our syntax highlighting *was* quadratic.

Investigating that, many brave hearts dug deeper and deeper into the
guts of rust-analyzer, only to get lost in a maze of traits delegating
to traits delegating to macros.

Eventually, matklad managed to peel off all layers of abstraction one by
one, until almost nothing was left. In fact, the issue was discovered in
the very foundation of the rust-analyzer -- in the syntax trees.

Worse, it was not a new problem, but rather a well-know, well-understood
and event (almost) well-fixed (!) performance bug.

The problem lies within `SyntaxNodePtr` type -- a light-weight "address"
of a node in a syntax tree [3]. Such pointers are used by rust-analyzer all
other the place to record relationships between IR nodes and the
original syntax.

Internally, the pointer to a syntax node is represented by node's range.
To "dereference" the pointer, you traverse the syntax tree from the
root, looking for the node with the right range. The inner loop of this
search is finding a node's child whose range contains the specified
range. This inner loop was implemented by naive linear search over all
the children. For wide trees, dereferencing a single `SyntaxNodePtr` was
linear. The problem with wide trees though is that they contain a lot of
nodes! And dereferencing pointers to all the nodes is quadratic in the
size of the file!

The solution to this problem is to speed up the children search --
rather than doing a linear lookup, we can use binary search to locate
the child with the desired interval.

Doing this optimization was one of the motivations (or rather, side
effects) of #6857. That's why `rowan` grew the useful
`child_or_token_at_range` method which does exactly this binary search.

But looks like we've never actually switch to this method? Oups.

Lesson learned: do not leave broken windows in the fundamental infra.
Otherwise, you'll have to repeatedly re-investigate the issue, by
digging from the top of the Everest down to the foundation!

[1]: https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/.60syntax_highlighting_not_quadratic.60.20failure/near/240811501
[2]: https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/Syntax.20highlighting.20is.20quadratic
[3]: https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/Syntax.20highlighting.20is.20quadratic/near/243412392
2021-06-21 20:14:38 +03:00
Aleksey Kladov
188b0f96f9 Add more docs 2021-05-22 16:53:47 +03:00
Aleksey Kladov
d7991f5f21 Document privacy invariant of SyntaxPtr 2020-10-06 20:06:14 +02:00
Aleksey Kladov
a1c187eef3 Rename ra_syntax -> syntax 2020-08-12 18:30:53 +02:00