-
-
Notifications
You must be signed in to change notification settings - Fork 951
linter: dynamically skip running rules that do not have the relevant node types #12223
Description
Context
In #8854, we experimented with adding improved metadata for rules to allow us to skip executing rules that don't apply. This yielded up to +8% performance improvements across small and big files. But the amount of code we needed to change didn't seem worth the performance improvement, so we gave up on the approach for now.
In #12178, I experimented with a different approach from the previous PR. Instead of modifying the return type of should_run: we can add or improve should_run for more rules which are currently run unconditionally. Using a fast lookup method to check if a node kind is in the AST, we can skip running rules on files that don't contain any nodes which are relevant to the rule.
Why we are doing this
Suppose that a file has 10,000 AST nodes, and we are running the linter with 100 rules enabled. The main loop of the linter will: iterate over all rules, and then iterate over all nodes, for each rule (ignoring jest nodes, symbols, and run-once rules for simplicity). This means that we will do 100 rules * 10,000 nodes = 1,000,000 iterations.
Now suppose this file doesn't contain any class definitions. There are a number of rules that check for class-specific behavior, like typescript/no-unnecessary-parameter-property-assignment, eslint/max-classes-per-file, and typescript/no-extraneous-class which we know will not report any diagnostics, because they can only report diagnostics if a class is in the AST. So, we know that some rules can be skipped just based on the types of AST nodes that are in the file. Assuming that we can quickly compute what types of AST nodes are in a given file, assume we're able to automatically skip 10 rules from the linter, so now we're only running 90 rules, down from 100. Now, we only need to do 90 rules * 10,000 nodes = 900,000 iterations.
So, by eliminating 10 rules out of the set of 100 rules that are enabled, we are able to reduce the number of iterations needed by 10%, which does somewhat correlate with walltime performance.
Process
- Identify a lint rule that has no
should_run, or only has a simpleshould_run, such as checking the source type or checking that TypeScript is enabled. - Update the rule to contain a check on the file's node types, so that if no relevant node types are in the file, the method returns
false.
Example PR: #12228
Metadata
Metadata
Assignees
Labels
Type
Fields
Give feedbackPriority
Effort
Start date
Target date