Skip to content

Commit 7fdd478

Browse files
committed
refactor(benchmarks): linter benchmark re-run parsing and semantic on each iteration (#13335)
Refactor linter benchmark so it parses and generates `Semantic` afresh before each measured iteration. This is more realistic usage - in real world you'd never lint the same file repeatedly - and may make cache utilization in the benchmark more realistic. It also prepares the way for upcoming changes where `ContextSubHost::new` will take an owned `Semantic` instead of `Rc<Semantic>`.
1 parent 827fe1c commit 7fdd478

File tree

1 file changed

+39
-24
lines changed

1 file changed

+39
-24
lines changed

tasks/benchmark/benches/linter.rs

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,47 @@ fn bench_linter(criterion: &mut Criterion) {
1919
let id = BenchmarkId::from_parameter(&file.file_name);
2020
let source_text = &file.source_text;
2121
let source_type = file.source_type;
22-
let allocator = Allocator::default();
23-
let ret = Parser::new(&allocator, source_text, source_type).parse();
24-
let path = Path::new("");
25-
let semantic_ret = SemanticBuilder::new()
26-
.with_build_jsdoc(true)
27-
.with_scope_tree_child_ids(true)
28-
.with_cfg(true)
29-
.build(&ret.program);
30-
let semantic = semantic_ret.semantic;
31-
let module_record = Arc::new(ModuleRecord::new(path, &ret.module_record, &semantic));
32-
let semantic = Rc::new(semantic);
33-
let external_plugin_store = ExternalPluginStore::default();
34-
let lint_config = ConfigStoreBuilder::all().build(&external_plugin_store).unwrap();
35-
let linter = Linter::new(
36-
LintOptions::default(),
37-
ConfigStore::new(lint_config, FxHashMap::default(), external_plugin_store),
38-
None,
39-
)
40-
.with_fix(FixKind::All);
22+
23+
// Create `Allocator` outside of `bench_function`, so same allocator is used for
24+
// both the warmup and measurement phases
25+
let mut allocator = Allocator::default();
26+
4127
group.bench_function(id, |b| {
42-
b.iter(|| {
43-
linter.run(
44-
path,
45-
vec![ContextSubHost::new(Rc::clone(&semantic), Arc::clone(&module_record), 0)],
46-
&allocator,
28+
b.iter_with_setup_wrapper(|runner| {
29+
// Reset allocator at start of each iteration
30+
allocator.reset();
31+
32+
let parser_ret = Parser::new(&allocator, source_text, source_type).parse();
33+
let path = Path::new("");
34+
let semantic_ret = SemanticBuilder::new()
35+
.with_build_jsdoc(true)
36+
.with_scope_tree_child_ids(true)
37+
.with_cfg(true)
38+
.build(&parser_ret.program);
39+
let semantic = semantic_ret.semantic;
40+
let module_record =
41+
Arc::new(ModuleRecord::new(path, &parser_ret.module_record, &semantic));
42+
let semantic = Rc::new(semantic);
43+
let external_plugin_store = ExternalPluginStore::default();
44+
let lint_config = ConfigStoreBuilder::all().build(&external_plugin_store).unwrap();
45+
let linter = Linter::new(
46+
LintOptions::default(),
47+
ConfigStore::new(lint_config, FxHashMap::default(), external_plugin_store),
48+
None,
4749
)
50+
.with_fix(FixKind::All);
51+
52+
runner.run(|| {
53+
linter.run(
54+
path,
55+
vec![ContextSubHost::new(
56+
Rc::clone(&semantic),
57+
Arc::clone(&module_record),
58+
0,
59+
)],
60+
&allocator,
61+
)
62+
});
4863
});
4964
});
5065
}

0 commit comments

Comments
 (0)