oxc-project
oxc
BlogDocsChangelog

perf(linter): apply small file optimization, up to 30% faster

#6600Merged
Comparing
10-15-perf_linter_iterate_over_each_rule_only_once
(
8387bac
) with
main
(
619d06f
)
CodSpeed Performance Gauge
+35%
Improvements
2
Untouched
28

Benchmarks

Improved

linter[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/linter.rs::linter::bench_linter
CodSpeed Performance Gauge
+35%
3.2 ms2.4 ms
linter[cal.com.tsx]
tasks/benchmark/benches/linter.rs::linter::bench_linter
CodSpeed Performance Gauge
+28%
1.3 s1 s

Passed

semantic[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
97.4 µs96.9 µs
lexer[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
24.1 µs24 µs
transformer[cal.com.tsx]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
30.7 ms30.7 ms
isolated-declarations[vue-id.ts]
tasks/benchmark/benches/isolated_declarations.rs::transformer::bench_isolated_declarations
CodSpeed Performance Gauge
0%
399 ms399 ms
semantic[antd.js]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
117.2 ms117.2 ms
minifier[typescript.js]
tasks/benchmark/benches/minifier.rs::minifier::bench_minifier
CodSpeed Performance Gauge
0%
520.3 ms520.3 ms
lexer[antd.js]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
22.4 ms22.4 ms
parser[pdf.mjs]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
17.5 ms17.5 ms
parser[antd.js]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
107.3 ms107.3 ms
minifier[antd.js]
tasks/benchmark/benches/minifier.rs::minifier::bench_minifier
CodSpeed Performance Gauge
0%
426.4 ms426.4 ms
parser[cal.com.tsx]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
24.7 ms24.7 ms
parser[checker.ts]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
53.6 ms53.6 ms
lexer[checker.ts]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
13.3 ms13.3 ms
codegen[checker.ts]
tasks/benchmark/benches/codegen.rs::codegen::bench_codegen
CodSpeed Performance Gauge
0%
27.2 ms27.2 ms
transformer[checker.ts]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
18.7 ms18.7 ms
semantic[checker.ts]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
72.1 ms72.1 ms
lexer[pdf.mjs]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
3.6 ms3.6 ms
minifier[react.development.js]
tasks/benchmark/benches/minifier.rs::minifier::bench_minifier
CodSpeed Performance Gauge
0%
2.9 ms2.9 ms
codegen_sourcemap[checker.ts]
tasks/benchmark/benches/codegen.rs::codegen::bench_codegen
CodSpeed Performance Gauge
0%
80.1 ms80.1 ms
transformer[pdf.mjs]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
7 ms7 ms
lexer[cal.com.tsx]
tasks/benchmark/benches/lexer.rs::lexer::bench_lexer
CodSpeed Performance Gauge
0%
5.5 ms5.5 ms
sourcemap[cal.com.tsx]
tasks/benchmark/benches/sourcemap.rs::sourcemap::bench_sourcemap
CodSpeed Performance Gauge
0%
62.7 ms62.7 ms
transformer[antd.js]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
47.3 ms47.3 ms
parser[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/parser.rs::parser::bench_parser
CodSpeed Performance Gauge
0%
78.7 µs78.7 µs
semantic[cal.com.tsx]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
35.9 ms35.9 ms
transformer[RadixUIAdoptionSection.jsx]
tasks/benchmark/benches/transformer.rs::transformer::bench_transformer
CodSpeed Performance Gauge
0%
156.9 µs157.5 µs
semantic[pdf.mjs]
tasks/benchmark/benches/semantic.rs::semantic::bench_semantic
CodSpeed Performance Gauge
0%
19.3 ms19.4 ms
linter[checker.ts]
tasks/benchmark/benches/linter.rs::linter::bench_linter
CodSpeed Performance Gauge
0%
2.4 s2.5 s

Commits

Click on a commit to change the comparison range
Base
main
619d06f
+35.14%
perf(linter): apply small file optimization, up to 30% faster (#6600) Theory: iterating over the rules three times has slightly worse cache locality, because the prior iterations have pushed `rule` out of the cache by the time we iterate over it again. By iterating over each rule only once, we improve cache performance (hopefully). We also don't need to collect rules to a Vec, so it saves some CPU/memory there too. In practice: the behavior here actually depends on the number of AST nodes that are in the program. If the number of nodes is large, then it's better to iterate over the nodes only once and iterate the rules multiple times. But if the number of nodes is small, then it's better to iterate over nodes multiple times and only iterate over the rules once. See this comment for more context: https://github.com/oxc-project/oxc/pull/6600#issuecomment-2427837715, as well as the comment inside the PR: https://github.com/oxc-project/oxc/pull/6600/files#diff-207225884c5e031ffd802bb99e4fbacbd8364b1343a1cec5485bf50f29186300R131-R143. In practice, this can make linting a file 1-45% faster, depending on the size of the file, number of AST nodes, number of files, CPU cache size, etc. To accommodate large and small files better, we have an explicit threshold of 200,000 AST nodes, which is an arbitrary number picked based on some benchmarks on my laptop. For large files, the linter behavior doesn't change. For small files, we switch to iterating over nodes in the inner loop and iterating over rules once in the outer loop.
8387bac
1 year ago
by camchenry
© 2026 CodSpeed Technology
Home Terms Privacy Docs