Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add text-based fastpaths into LS token matching #41924

Merged
merged 6 commits into from
Dec 15, 2020

Conversation

weswigham
Copy link
Member

This takes the runtime of the excessivelyLargeArrayLiteralCompletions.ts fourslash test down from ~36s on my machine (near the timeout limit) to 1s.

A bit of history: The test in question was added recently, in #40953, as a perf-monitoring test. The initial fix did make the perf much better (going from "spin forever" to 11s is pretty good), however its perf has been creeping back up over the last two months, to the point where on @andrewbranch 's machine it started timing out. So I took a look again to see what was going on. The low-level operation that we spend all the time doing is matching tokens, and that's what I'd algorithmically optimized in #40953. In this PR, I took a look from the top down - the reason we're matching tokens, at all, is to determine if the location we're looking for completions at is a type argument position (which in turn filters the completion list) - to do so, we match all braces backwards from the cursor until we run into a < which isn't contained within a set of matched braces. Unfortunately, in the test given, there are thousands of braces to match, so even though the token finding within the source file is pretty efficient(tm), we have a lot of work to do, still, since we essentially are forced to find almost every other token in the file. And that's where this PR comes in: in two phases, we use textual heuristics to quickly stop or speed up that token matching process.

@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Dec 10, 2020
@@ -1391,7 +1391,23 @@ namespace ts {
return isInsideJsxElementTraversal(getTokenAtPosition(sourceFile, position));
}

export function findPrecedingMatchingToken(token: Node, matchingTokenKind: SyntaxKind, sourceFile: SourceFile) {
export function findPrecedingMatchingToken(token: Node, matchingTokenKind: SyntaxKind.OpenBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.OpenBracketToken, sourceFile: SourceFile) {
Copy link
Member Author

Choose a reason for hiding this comment

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

The changes to this function were able to bring the test runtime from ~36s to ~10s on my machine. Just looking for the likely token position using lastIndexOf gives a great improvement,

src/services/utilities.ts Outdated Show resolved Hide resolved
Copy link
Member

@andrewbranch andrewbranch left a comment

Choose a reason for hiding this comment

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

👏

src/services/utilities.ts Outdated Show resolved Hide resolved
src/services/utilities.ts Outdated Show resolved Hide resolved
src/services/utilities.ts Outdated Show resolved Hide resolved
src/services/utilities.ts Outdated Show resolved Hide resolved
weswigham and others added 5 commits December 15, 2020 13:09
Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
@weswigham weswigham merged commit b869c9c into microsoft:master Dec 15, 2020
@weswigham weswigham deleted the token-matching-fastpaths branch December 15, 2020 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants