perf(css/minifier): Remove redundant clone (#6579)

This commit is contained in:
Donny/강동윤 2022-12-06 15:20:05 +09:00 committed by GitHub
parent a475f61ac3
commit 70ac0286e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 31 deletions

View File

@ -1,5 +1,5 @@
use is_macro::Is; use is_macro::Is;
use swc_common::{ast_node, EqIgnoreSpan, Span}; use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
use crate::{ use crate::{
AlphaValue, AtRule, CalcSum, CmykComponent, Color, ComplexSelector, DashedIdent, Delimiter, AlphaValue, AtRule, CalcSum, CmykComponent, Color, ComplexSelector, DashedIdent, Delimiter,
@ -46,6 +46,12 @@ pub enum QualifiedRulePrelude {
ListOfComponentValues(ListOfComponentValues), ListOfComponentValues(ListOfComponentValues),
} }
impl Take for QualifiedRulePrelude {
fn dummy() -> Self {
Self::SelectorList(Take::dummy())
}
}
#[ast_node] #[ast_node]
#[derive(Eq, Hash, Is, EqIgnoreSpan)] #[derive(Eq, Hash, Is, EqIgnoreSpan)]
pub enum StyleBlock { pub enum StyleBlock {
@ -67,6 +73,16 @@ pub struct SimpleBlock {
pub value: Vec<ComponentValue>, pub value: Vec<ComponentValue>,
} }
impl Take for SimpleBlock {
fn dummy() -> Self {
Self {
span: Take::dummy(),
name: Take::dummy(),
value: Take::dummy(),
}
}
}
#[ast_node("Function")] #[ast_node("Function")]
#[derive(Eq, Hash, EqIgnoreSpan)] #[derive(Eq, Hash, EqIgnoreSpan)]
pub struct Function { pub struct Function {

View File

@ -12,6 +12,15 @@ pub struct SelectorList {
pub children: Vec<ComplexSelector>, pub children: Vec<ComplexSelector>,
} }
impl Take for SelectorList {
fn dummy() -> Self {
Self {
span: Take::dummy(),
children: Take::dummy(),
}
}
}
#[ast_node("SelectorList")] #[ast_node("SelectorList")]
#[derive(Eq, Hash, EqIgnoreSpan)] #[derive(Eq, Hash, EqIgnoreSpan)]
pub struct ForgivingSelectorList { pub struct ForgivingSelectorList {

View File

@ -6,7 +6,7 @@ use std::{
use is_macro::Is; use is_macro::Is;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use swc_atoms::{Atom, JsWord}; use swc_atoms::{Atom, JsWord};
use swc_common::{ast_node, EqIgnoreSpan, Span}; use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
#[ast_node("PreservedToken")] #[ast_node("PreservedToken")]
#[derive(Eq, Hash, EqIgnoreSpan)] #[derive(Eq, Hash, EqIgnoreSpan)]
@ -15,6 +15,15 @@ pub struct TokenAndSpan {
pub token: Token, pub token: Token,
} }
impl Take for TokenAndSpan {
fn dummy() -> Self {
Self {
span: Take::dummy(),
token: Take::dummy(),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Is, EqIgnoreSpan)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Is, EqIgnoreSpan)]
#[cfg_attr( #[cfg_attr(
feature = "rkyv", feature = "rkyv",
@ -147,6 +156,12 @@ pub enum Token {
RBrace, RBrace,
} }
impl Take for Token {
fn dummy() -> Self {
Self::Semi
}
}
#[allow(clippy::derive_hash_xor_eq)] #[allow(clippy::derive_hash_xor_eq)]
#[allow(clippy::transmute_float_to_int)] #[allow(clippy::transmute_float_to_int)]
impl Hash for Token { impl Hash for Token {

View File

@ -1,7 +1,9 @@
use std::mem::take; use std::mem::take;
use swc_atoms::{js_word, JsWord}; use swc_atoms::{js_word, JsWord};
use swc_common::{collections::AHashMap, EqIgnoreSpan, Span, Spanned, SyntaxContext}; use swc_common::{
collections::AHashMap, util::take::Take, EqIgnoreSpan, Span, Spanned, SyntaxContext,
};
use swc_css_ast::*; use swc_css_ast::*;
use swc_css_visit::{Visit, VisitMutWith, VisitWith}; use swc_css_visit::{Visit, VisitMutWith, VisitWith};
@ -144,10 +146,14 @@ impl Compressor {
} }
} }
fn merge_selector_list(&self, left: &SelectorList, right: &SelectorList) -> SelectorList { fn merge_selector_list(
let mut children = left.children.clone(); &self,
left: &mut SelectorList,
right: &mut SelectorList,
) -> SelectorList {
let mut children = left.children.take();
children.extend(right.children.clone()); children.extend(right.children.take());
SelectorList { SelectorList {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()), span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
@ -157,12 +163,12 @@ impl Compressor {
fn merge_relative_selector_list( fn merge_relative_selector_list(
&self, &self,
left: &RelativeSelectorList, left: &mut RelativeSelectorList,
right: &RelativeSelectorList, right: &mut RelativeSelectorList,
) -> RelativeSelectorList { ) -> RelativeSelectorList {
let mut children = left.children.clone(); let mut children = left.children.take();
children.extend(right.children.clone()); children.extend(right.children.take());
RelativeSelectorList { RelativeSelectorList {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()), span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
@ -170,10 +176,10 @@ impl Compressor {
} }
} }
fn merge_simple_block(&self, left: &SimpleBlock, right: &SimpleBlock) -> SimpleBlock { fn merge_simple_block(&self, left: &mut SimpleBlock, right: &mut SimpleBlock) -> SimpleBlock {
let mut value = left.value.clone(); let mut value = left.value.take();
value.extend(right.value.clone()); value.extend(right.value.take());
SimpleBlock { SimpleBlock {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()), span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
@ -212,8 +218,8 @@ impl Compressor {
fn try_merge_qualified_rules( fn try_merge_qualified_rules(
&mut self, &mut self,
left: &QualifiedRule, left: &mut QualifiedRule,
right: &QualifiedRule, right: &mut QualifiedRule,
) -> Option<QualifiedRule> { ) -> Option<QualifiedRule> {
if !self.can_merge_qualified_rules(left, right) { if !self.can_merge_qualified_rules(left, right) {
return None; return None;
@ -222,7 +228,7 @@ impl Compressor {
// Merge when declarations are exactly equal // Merge when declarations are exactly equal
// e.g. h1 { color: red } h2 { color: red } // e.g. h1 { color: red } h2 { color: red }
if left.block.eq_ignore_span(&right.block) { if left.block.eq_ignore_span(&right.block) {
match (&left.prelude, &right.prelude) { match (&mut left.prelude, &mut right.prelude) {
( (
QualifiedRulePrelude::SelectorList(prev_selector_list), QualifiedRulePrelude::SelectorList(prev_selector_list),
QualifiedRulePrelude::SelectorList(current_selector_list), QualifiedRulePrelude::SelectorList(current_selector_list),
@ -232,7 +238,7 @@ impl Compressor {
let mut qualified_rule = QualifiedRule { let mut qualified_rule = QualifiedRule {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()), span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
prelude: QualifiedRulePrelude::SelectorList(selector_list), prelude: QualifiedRulePrelude::SelectorList(selector_list),
block: left.block.clone(), block: left.block.take(),
}; };
qualified_rule.visit_mut_children_with(self); qualified_rule.visit_mut_children_with(self);
@ -250,7 +256,7 @@ impl Compressor {
let mut qualified_rule = QualifiedRule { let mut qualified_rule = QualifiedRule {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()), span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
prelude: QualifiedRulePrelude::RelativeSelectorList(relative_selector_list), prelude: QualifiedRulePrelude::RelativeSelectorList(relative_selector_list),
block: left.block.clone(), block: left.block.take(),
}; };
qualified_rule.visit_mut_children_with(self); qualified_rule.visit_mut_children_with(self);
@ -264,10 +270,10 @@ impl Compressor {
// Merge when both selectors are exactly equal // Merge when both selectors are exactly equal
// e.g. a { color: blue } a { font-weight: bold } // e.g. a { color: blue } a { font-weight: bold }
if left.prelude.eq_ignore_span(&right.prelude) { if left.prelude.eq_ignore_span(&right.prelude) {
let block = self.merge_simple_block(&left.block, &right.block); let block = self.merge_simple_block(&mut left.block, &mut right.block);
let mut qualified_rule = QualifiedRule { let mut qualified_rule = QualifiedRule {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()), span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
prelude: left.prelude.clone(), prelude: left.prelude.take(),
block, block,
}; };
@ -299,14 +305,14 @@ impl Compressor {
} }
} }
fn try_merge_at_rule(&mut self, left: &AtRule, right: &AtRule) -> Option<AtRule> { fn try_merge_at_rule(&mut self, left: &mut AtRule, right: &mut AtRule) -> Option<AtRule> {
// Merge when both at-rule's prelude is exactly equal // Merge when both at-rule's prelude is exactly equal
// e.g. // e.g.
// @media print { .color { color: red; } } // @media print { .color { color: red; } }
// @media print { .color { color: blue; } } // @media print { .color { color: blue; } }
if left.prelude.eq_ignore_span(&right.prelude) { if left.prelude.eq_ignore_span(&right.prelude) {
if let Some(left_block) = &left.block { if let Some(left_block) = &mut left.block {
if let Some(right_block) = &right.block { if let Some(right_block) = &mut right.block {
let block = self.merge_simple_block(left_block, right_block); let block = self.merge_simple_block(left_block, right_block);
let mut at_rule = AtRule { let mut at_rule = AtRule {
span: Span::new( span: Span::new(
@ -315,7 +321,7 @@ impl Compressor {
SyntaxContext::empty(), SyntaxContext::empty(),
), ),
name: left.name.clone(), name: left.name.clone(),
prelude: left.prelude.clone(), prelude: left.prelude.take(),
block: Some(block), block: Some(block),
}; };
@ -350,7 +356,7 @@ impl Compressor {
if self.is_mergeable_at_rule(at_rule) if self.is_mergeable_at_rule(at_rule)
&& matches!(prev_rule, Some(Rule::AtRule(_))) => && matches!(prev_rule, Some(Rule::AtRule(_))) =>
{ {
if let Some(Rule::AtRule(box prev_rule)) = &prev_rule { if let Some(Rule::AtRule(box prev_rule)) = &mut prev_rule {
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) { if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
*rule = Rule::AtRule(Box::new(at_rule)); *rule = Rule::AtRule(Box::new(at_rule));
@ -363,7 +369,7 @@ impl Compressor {
Rule::QualifiedRule(box qualified_rule @ QualifiedRule { .. }) Rule::QualifiedRule(box qualified_rule @ QualifiedRule { .. })
if matches!(prev_rule, Some(Rule::QualifiedRule(_))) => if matches!(prev_rule, Some(Rule::QualifiedRule(_))) =>
{ {
if let Some(Rule::QualifiedRule(box prev_rule)) = &prev_rule { if let Some(Rule::QualifiedRule(box prev_rule)) = &mut prev_rule {
if let Some(qualified_rule) = if let Some(qualified_rule) =
self.try_merge_qualified_rules(prev_rule, qualified_rule) self.try_merge_qualified_rules(prev_rule, qualified_rule)
{ {
@ -478,7 +484,8 @@ impl Compressor {
ComponentValue::Rule(box Rule::AtRule(box at_rule @ AtRule { .. })) ComponentValue::Rule(box Rule::AtRule(box at_rule @ AtRule { .. }))
if prev_rule.is_some() && self.is_mergeable_at_rule(at_rule) => if prev_rule.is_some() && self.is_mergeable_at_rule(at_rule) =>
{ {
if let Some(ComponentValue::Rule(box Rule::AtRule(box prev_rule))) = &prev_rule if let Some(ComponentValue::Rule(box Rule::AtRule(box prev_rule))) =
&mut prev_rule
{ {
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) { if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
*rule = ComponentValue::Rule(Box::new(Rule::AtRule(Box::new(at_rule)))); *rule = ComponentValue::Rule(Box::new(Rule::AtRule(Box::new(at_rule))));
@ -493,7 +500,7 @@ impl Compressor {
if prev_rule.is_some() && self.is_mergeable_at_rule(at_rule) => if prev_rule.is_some() && self.is_mergeable_at_rule(at_rule) =>
{ {
if let Some(ComponentValue::StyleBlock(box StyleBlock::AtRule(box prev_rule))) = if let Some(ComponentValue::StyleBlock(box StyleBlock::AtRule(box prev_rule))) =
&prev_rule &mut prev_rule
{ {
if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) { if let Some(at_rule) = self.try_merge_at_rule(prev_rule, at_rule) {
*rule = ComponentValue::StyleBlock(Box::new(StyleBlock::AtRule( *rule = ComponentValue::StyleBlock(Box::new(StyleBlock::AtRule(
@ -510,7 +517,7 @@ impl Compressor {
box qualified_rule @ QualifiedRule { .. }, box qualified_rule @ QualifiedRule { .. },
)) if prev_rule.is_some() => { )) if prev_rule.is_some() => {
if let Some(ComponentValue::Rule(box Rule::QualifiedRule(box prev_rule))) = if let Some(ComponentValue::Rule(box Rule::QualifiedRule(box prev_rule))) =
&prev_rule &mut prev_rule
{ {
if let Some(qualified_rule) = if let Some(qualified_rule) =
self.try_merge_qualified_rules(prev_rule, qualified_rule) self.try_merge_qualified_rules(prev_rule, qualified_rule)
@ -530,7 +537,7 @@ impl Compressor {
)) if prev_rule.is_some() => { )) if prev_rule.is_some() => {
if let Some(ComponentValue::StyleBlock(box StyleBlock::QualifiedRule( if let Some(ComponentValue::StyleBlock(box StyleBlock::QualifiedRule(
box prev_rule, box prev_rule,
))) = &prev_rule ))) = &mut prev_rule
{ {
if let Some(qualified_rule) = if let Some(qualified_rule) =
self.try_merge_qualified_rules(prev_rule, qualified_rule) self.try_merge_qualified_rules(prev_rule, qualified_rule)

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -eu
export RUST_LOG=off
export MIMALLOC_SHOW_STATS=1
cargo profile instruments --release -t time --features swc_common/concurrent --bench lexer -- --bench --color $@

View File

@ -4,4 +4,4 @@ set -eu
export RUST_LOG=off export RUST_LOG=off
export MIMALLOC_SHOW_STATS=1 export MIMALLOC_SHOW_STATS=1
cargo profile instruments --release -t time --features swc_common/concurrent --bench parser -- --bench --color cargo profile instruments --release -t time --features swc_common/concurrent --bench parser -- --bench --color $@