Skip to content

Commit

Permalink
perf(es/lints): Configure a benchmark for ES lints (#9833)
Browse files Browse the repository at this point in the history
**Description:**

The lints are causing perf issues for turbopack.
  • Loading branch information
kdy1 authored Jan 3, 2025
1 parent d9f1887 commit 734ec21
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 4 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 16 additions & 4 deletions crates/swc_ecma_lints/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,22 @@ swc_ecma_utils = { version = "6.0.0", path = "../swc_ecma_utils" }
swc_ecma_visit = { version = "5.0.0", path = "../swc_ecma_visit" }

[dev-dependencies]
swc_ecma_codegen = { version = "5.0.1", path = "../swc_ecma_codegen" }
swc_ecma_parser = { version = "6.0.1", path = "../swc_ecma_parser" }
swc_ecma_transforms_base = { version = "6.0.2", path = "../swc_ecma_transforms_base" }
testing = { version = "5.0.0", path = "../testing" }
anyhow = { workspace = true }
codspeed-criterion-compat = { workspace = true }
criterion = { workspace = true }
pretty_assertions = { workspace = true }
swc_ecma_codegen = { version = "5.0.1", path = "../swc_ecma_codegen" }
swc_ecma_parser = { version = "6.0.1", path = "../swc_ecma_parser" }
swc_ecma_testing = { version = "5.0.0", path = "../swc_ecma_testing" }
swc_ecma_transforms_base = { version = "6.0.2", path = "../swc_ecma_transforms_base" }
swc_malloc = { version = "1.0.0", path = "../swc_malloc" }
testing = { version = "5.0.0", path = "../testing" }
walkdir = { workspace = true }

[features]
non_critical_lints = []


[[bench]]
harness = false
name = "all"
109 changes: 109 additions & 0 deletions crates/swc_ecma_lints/benches/all.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
extern crate swc_malloc;

use std::fs::read_to_string;

use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Criterion};
use swc_common::{
errors::{Handler, HANDLER},
sync::Lrc,
FileName, Globals, Mark, SourceMap, SyntaxContext, GLOBALS,
};
use swc_ecma_ast::{EsVersion, Program};
use swc_ecma_lints::{config::LintConfig, rule::Rule, rules::LintParams};
use swc_ecma_parser::parse_file_as_module;
use swc_ecma_transforms_base::resolver;
use swc_ecma_visit::{Visit, VisitWith};

pub fn bench_files(c: &mut Criterion) {
let mut group = c.benchmark_group("es/lints/libs");
group.sample_size(10);

let mut bench_file = |name: &str| {
group.bench_function(format!("es/lints/libs/{}", name), |b| {
let src =
read_to_string(format!("../swc_ecma_minifier/benches/full/{}.js", name)).unwrap();

let globals = Globals::default();
GLOBALS.set(&globals, || {
let cm = Lrc::new(SourceMap::default());
let handler = Handler::with_tty_emitter(
swc_common::errors::ColorConfig::Always,
true,
false,
Some(cm.clone()),
);

let fm = cm.new_source_file(FileName::Anon.into(), src);

let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();

let program = parse_file_as_module(
&fm,
Default::default(),
Default::default(),
None,
&mut Vec::new(),
)
.map_err(|err| {
err.into_diagnostic(&handler).emit();
})
.map(Program::Module)
.map(|module| module.apply(resolver(unresolved_mark, top_level_mark, false)))
.unwrap();

b.iter(|| {
GLOBALS.set(&globals, || {
HANDLER.set(&handler, || {
run(cm.clone(), program.clone(), unresolved_mark, top_level_mark)
});
});
});
});
});
};

bench_file("antd");
bench_file("d3");
bench_file("echarts");
bench_file("jquery");
bench_file("lodash");
bench_file("moment");
bench_file("react");
bench_file("terser");
bench_file("three");
bench_file("typescript");
bench_file("victory");
bench_file("vue");
}

criterion_group!(files, bench_files);
criterion_main!(files);

fn run(cm: Lrc<SourceMap>, program: Program, unresolved_mark: Mark, top_level_mark: Mark) {
let rules = swc_ecma_lints::rules::all(LintParams {
program: &program,
lint_config: &LintConfig::default(),
unresolved_ctxt: SyntaxContext::empty().apply_mark(unresolved_mark),
top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark),
es_version: EsVersion::EsNext,
source_map: cm.clone(),
});

let mut visitor = black_box(Visitors(rules));

program.visit_with(&mut visitor);
}

struct Visitors(Vec<Box<dyn Rule>>);

impl Visit for Visitors {
fn visit_program(&mut self, program: &Program) {
for rule in self.0.iter_mut() {
match program {
Program::Module(module) => rule.lint_module(module),
Program::Script(script) => rule.lint_script(script),
}
}
}
}

0 comments on commit 734ec21

Please sign in to comment.