From d669454157da62f9bec4b078230e4e372efd91e3 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Fri, 10 Jun 2022 08:45:32 +0300 Subject: [PATCH] perf(html/parser): Add a benchmark for document fragment (#4920) --- crates/swc_html_parser/benches/compare.rs | 134 ++++++++++++++++++++-- crates/swc_html_parser/benches/lexer.rs | 8 +- crates/swc_html_parser/benches/parser.rs | 46 +++++++- 3 files changed, 167 insertions(+), 21 deletions(-) diff --git a/crates/swc_html_parser/benches/compare.rs b/crates/swc_html_parser/benches/compare.rs index 35f223d591d..c556308fe19 100644 --- a/crates/swc_html_parser/benches/compare.rs +++ b/crates/swc_html_parser/benches/compare.rs @@ -2,13 +2,13 @@ extern crate swc_node_base; use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; use swc_common::{input::StringInput, FileName, Span, SyntaxContext, DUMMY_SP}; -use swc_html_ast::Document; +use swc_html_ast::{Document, DocumentFragment, Element, Namespace}; use swc_html_parser::{lexer::Lexer, parser::Parser}; use swc_html_visit::{Fold, FoldWith, VisitMut, VisitMutWith}; static SOURCE: &str = include_str!("files/github_com_17_05_2022.html"); -fn run(b: &mut Bencher, mut op: F) +fn run_document(b: &mut Bencher, mut op: F) where F: FnMut(Document) -> Document, { @@ -30,10 +30,43 @@ where }); } -fn bench_cases(c: &mut Criterion) { - c.bench_function("es/visitor/compare/clone", |b| run(b, |m: Document| m)); +fn run_document_fragment(b: &mut Bencher, mut op: F) +where + F: FnMut(DocumentFragment) -> DocumentFragment, +{ + let _ = ::testing::run_test(false, |cm, _| { + let fm = cm.new_source_file(FileName::Anon, SOURCE.into()); - c.bench_function("es/visitor/compare/visit_mut_span", |b| { + let lexer = Lexer::new(StringInput::from(&*fm)); + let mut parser = Parser::new(lexer, Default::default()); + let document_fragment: DocumentFragment = parser + .parse_document_fragment(Element { + span: Default::default(), + tag_name: "template".into(), + namespace: Namespace::HTML, + attributes: vec![], + children: vec![], + content: None, + }) + .unwrap(); + + b.iter(|| { + let document_fragment = document_fragment.clone(); + let document_fragment = op(document_fragment); + + black_box(document_fragment) + }); + + Ok(()) + }); +} + +fn bench_cases(c: &mut Criterion) { + c.bench_function("html/document/visitor/compare/clone", |b| { + run_document(b, |m: Document| m) + }); + + c.bench_function("html/document/visitor/compare/visit_mut_span", |b| { struct RespanVisitMut; impl VisitMut for RespanVisitMut { @@ -42,14 +75,14 @@ fn bench_cases(c: &mut Criterion) { } } - run(b, |mut m| { + run_document(b, |mut m| { m.visit_mut_with(&mut RespanVisitMut); m }); }); - c.bench_function("es/visitor/compare/visit_mut_span_panic", |b| { + c.bench_function("html/document/visitor/compare/visit_mut_span_panic", |b| { struct RespanVisitMut; impl VisitMut for RespanVisitMut { @@ -62,14 +95,14 @@ fn bench_cases(c: &mut Criterion) { } } - run(b, |mut m| { + run_document(b, |mut m| { m.visit_mut_with(&mut RespanVisitMut); m }); }); - c.bench_function("es/visitor/compare/fold_span", |b| { + c.bench_function("html/document/visitor/compare/fold_span", |b| { struct RespanFold; impl Fold for RespanFold { @@ -78,10 +111,10 @@ fn bench_cases(c: &mut Criterion) { } } - run(b, |m| m.fold_with(&mut RespanFold)); + run_document(b, |m| m.fold_with(&mut RespanFold)); }); - c.bench_function("es/visitor/compare/fold_span_panic", |b| { + c.bench_function("html/document/visitor/compare/fold_span_panic", |b| { struct RespanFold; impl Fold for RespanFold { @@ -94,8 +127,85 @@ fn bench_cases(c: &mut Criterion) { } } - run(b, |m| m.fold_with(&mut RespanFold)); + run_document(b, |m| m.fold_with(&mut RespanFold)); }); + + c.bench_function("html/document_fragment/visitor/compare/clone", |b| { + run_document_fragment(b, |m: DocumentFragment| m) + }); + + c.bench_function( + "html/document_fragment/visitor/compare/visit_mut_span", + |b| { + struct RespanVisitMut; + + impl VisitMut for RespanVisitMut { + fn visit_mut_span(&mut self, span: &mut Span) { + *span = DUMMY_SP; + } + } + + run_document_fragment(b, |mut m| { + m.visit_mut_with(&mut RespanVisitMut); + + m + }); + }, + ); + + c.bench_function( + "html/document_fragment/visitor/compare/visit_mut_span_panic", + |b| { + struct RespanVisitMut; + + impl VisitMut for RespanVisitMut { + fn visit_mut_span(&mut self, span: &mut Span) { + if span.ctxt != SyntaxContext::empty() { + panic!() + } + + *span = DUMMY_SP; + } + } + + run_document_fragment(b, |mut m| { + m.visit_mut_with(&mut RespanVisitMut); + + m + }); + }, + ); + + c.bench_function("html/document_fragment/visitor/compare/fold_span", |b| { + struct RespanFold; + + impl Fold for RespanFold { + fn fold_span(&mut self, _: Span) -> Span { + DUMMY_SP + } + } + + run_document_fragment(b, |m| m.fold_with(&mut RespanFold)); + }); + + c.bench_function( + "html/document_fragment/visitor/compare/fold_span_panic", + |b| { + struct RespanFold; + + impl Fold for RespanFold { + fn fold_span(&mut self, s: Span) -> Span { + if s.ctxt != SyntaxContext::empty() { + panic!() + } + + DUMMY_SP + } + } + + run_document_fragment(b, |m| m.fold_with(&mut RespanFold)); + }, + ); } criterion_group!(benches, bench_cases); diff --git a/crates/swc_html_parser/benches/lexer.rs b/crates/swc_html_parser/benches/lexer.rs index d6ff17aaa9c..25da2cbab74 100644 --- a/crates/swc_html_parser/benches/lexer.rs +++ b/crates/swc_html_parser/benches/lexer.rs @@ -4,7 +4,7 @@ use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; use swc_common::{input::StringInput, FileName}; use swc_html_parser::lexer::Lexer; -fn bench_document(b: &mut Bencher, src: &'static str) { +fn bench_lexer(b: &mut Bencher, src: &'static str) { let _ = ::testing::run_test(false, |cm, _| { let fm = cm.new_source_file(FileName::Anon, src.into()); @@ -22,15 +22,15 @@ fn bench_document(b: &mut Bencher, src: &'static str) { fn bench_files(c: &mut Criterion) { c.bench_function("html/lexer/css_2021_spec", |b| { - bench_document(b, include_str!("./files/css_2021_spec.html")) + bench_lexer(b, include_str!("./files/css_2021_spec.html")) }); c.bench_function("html/lexer/github_com_17_05_2022", |b| { - bench_document(b, include_str!("./files/github_com_17_05_2022.html")) + bench_lexer(b, include_str!("./files/github_com_17_05_2022.html")) }); c.bench_function("html/lexer/stackoverflow_com_17_05_2022", |b| { - bench_document(b, include_str!("./files/stackoverflow_com_17_05_2022.html")) + bench_lexer(b, include_str!("./files/stackoverflow_com_17_05_2022.html")) }); } diff --git a/crates/swc_html_parser/benches/parser.rs b/crates/swc_html_parser/benches/parser.rs index 4c26b651712..20e09998f3c 100644 --- a/crates/swc_html_parser/benches/parser.rs +++ b/crates/swc_html_parser/benches/parser.rs @@ -2,10 +2,9 @@ extern crate swc_node_base; use criterion::{black_box, criterion_group, criterion_main, Bencher, Criterion}; use swc_common::{input::StringInput, FileName}; +use swc_html_ast::{Element, Namespace}; use swc_html_parser::{lexer::Lexer, parser::Parser}; -// TODO bench document_fragment when it will be finished - fn bench_document(b: &mut Bencher, src: &'static str) { let _ = ::testing::run_test(false, |cm, _| { let fm = cm.new_source_file(FileName::Anon, src.into()); @@ -23,18 +22,55 @@ fn bench_document(b: &mut Bencher, src: &'static str) { }); } +fn bench_document_fragment(b: &mut Bencher, src: &'static str) { + let _ = ::testing::run_test(false, |cm, _| { + let fm = cm.new_source_file(FileName::Anon, src.into()); + + b.iter(|| { + let _ = black_box({ + let lexer = Lexer::new(StringInput::from(&*fm)); + let mut parser = Parser::new(lexer, Default::default()); + + parser.parse_document_fragment(Element { + span: Default::default(), + tag_name: "template".into(), + namespace: Namespace::HTML, + attributes: vec![], + children: vec![], + content: None, + }) + }); + }); + + Ok(()) + }); +} + fn bench_files(c: &mut Criterion) { - c.bench_function("html/parser/css_2021_spec", |b| { + c.bench_function("html/parser_document/css_2021_spec", |b| { bench_document(b, include_str!("./files/css_2021_spec.html")) }); - c.bench_function("html/parser/github_com_17_05_2022", |b| { + c.bench_function("html/parser_document/github_com_17_05_2022", |b| { bench_document(b, include_str!("./files/github_com_17_05_2022.html")) }); - c.bench_function("html/parser/stackoverflow_com_17_05_2022", |b| { + c.bench_function("html/parser_document/stackoverflow_com_17_05_2022", |b| { bench_document(b, include_str!("./files/stackoverflow_com_17_05_2022.html")) }); + + c.bench_function("html/parser_document_fragment/css_2021_spec", |b| { + bench_document_fragment(b, include_str!("./files/css_2021_spec.html")) + }); + + c.bench_function("html/parser_document_fragment/github_com_17_05_2022", |b| { + bench_document_fragment(b, include_str!("./files/github_com_17_05_2022.html")) + }); + + c.bench_function( + "html/parser_document_fragment/stackoverflow_com_17_05_2022", + |b| bench_document_fragment(b, include_str!("./files/stackoverflow_com_17_05_2022.html")), + ); } criterion_group!(benches, bench_files);