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

View File

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

View File

@ -6,7 +6,7 @@ use std::{
use is_macro::Is;
use serde::{Deserialize, Serialize};
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")]
#[derive(Eq, Hash, EqIgnoreSpan)]
@ -15,6 +15,15 @@ pub struct TokenAndSpan {
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)]
#[cfg_attr(
feature = "rkyv",
@ -147,6 +156,12 @@ pub enum Token {
RBrace,
}
impl Take for Token {
fn dummy() -> Self {
Self::Semi
}
}
#[allow(clippy::derive_hash_xor_eq)]
#[allow(clippy::transmute_float_to_int)]
impl Hash for Token {

View File

@ -1,7 +1,9 @@
use std::mem::take;
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_visit::{Visit, VisitMutWith, VisitWith};
@ -144,10 +146,14 @@ impl Compressor {
}
}
fn merge_selector_list(&self, left: &SelectorList, right: &SelectorList) -> SelectorList {
let mut children = left.children.clone();
fn merge_selector_list(
&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 {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
@ -157,12 +163,12 @@ impl Compressor {
fn merge_relative_selector_list(
&self,
left: &RelativeSelectorList,
right: &RelativeSelectorList,
left: &mut RelativeSelectorList,
right: &mut 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 {
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 {
let mut value = left.value.clone();
fn merge_simple_block(&self, left: &mut SimpleBlock, right: &mut SimpleBlock) -> SimpleBlock {
let mut value = left.value.take();
value.extend(right.value.clone());
value.extend(right.value.take());
SimpleBlock {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
@ -212,8 +218,8 @@ impl Compressor {
fn try_merge_qualified_rules(
&mut self,
left: &QualifiedRule,
right: &QualifiedRule,
left: &mut QualifiedRule,
right: &mut QualifiedRule,
) -> Option<QualifiedRule> {
if !self.can_merge_qualified_rules(left, right) {
return None;
@ -222,7 +228,7 @@ impl Compressor {
// Merge when declarations are exactly equal
// e.g. h1 { color: red } h2 { color: red }
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(current_selector_list),
@ -232,7 +238,7 @@ impl Compressor {
let mut qualified_rule = QualifiedRule {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
prelude: QualifiedRulePrelude::SelectorList(selector_list),
block: left.block.clone(),
block: left.block.take(),
};
qualified_rule.visit_mut_children_with(self);
@ -250,7 +256,7 @@ impl Compressor {
let mut qualified_rule = QualifiedRule {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
prelude: QualifiedRulePrelude::RelativeSelectorList(relative_selector_list),
block: left.block.clone(),
block: left.block.take(),
};
qualified_rule.visit_mut_children_with(self);
@ -264,10 +270,10 @@ impl Compressor {
// Merge when both selectors are exactly equal
// e.g. a { color: blue } a { font-weight: bold }
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 {
span: Span::new(left.span_lo(), right.span_hi(), SyntaxContext::empty()),
prelude: left.prelude.clone(),
prelude: left.prelude.take(),
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
// e.g.
// @media print { .color { color: red; } }
// @media print { .color { color: blue; } }
if left.prelude.eq_ignore_span(&right.prelude) {
if let Some(left_block) = &left.block {
if let Some(right_block) = &right.block {
if let Some(left_block) = &mut left.block {
if let Some(right_block) = &mut right.block {
let block = self.merge_simple_block(left_block, right_block);
let mut at_rule = AtRule {
span: Span::new(
@ -315,7 +321,7 @@ impl Compressor {
SyntaxContext::empty(),
),
name: left.name.clone(),
prelude: left.prelude.clone(),
prelude: left.prelude.take(),
block: Some(block),
};
@ -350,7 +356,7 @@ impl Compressor {
if self.is_mergeable_at_rule(at_rule)
&& 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) {
*rule = Rule::AtRule(Box::new(at_rule));
@ -363,7 +369,7 @@ impl Compressor {
Rule::QualifiedRule(box qualified_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) =
self.try_merge_qualified_rules(prev_rule, qualified_rule)
{
@ -478,7 +484,8 @@ impl Compressor {
ComponentValue::Rule(box Rule::AtRule(box at_rule @ AtRule { .. }))
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) {
*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 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) {
*rule = ComponentValue::StyleBlock(Box::new(StyleBlock::AtRule(
@ -510,7 +517,7 @@ impl Compressor {
box qualified_rule @ QualifiedRule { .. },
)) if prev_rule.is_some() => {
if let Some(ComponentValue::Rule(box Rule::QualifiedRule(box prev_rule))) =
&prev_rule
&mut prev_rule
{
if let Some(qualified_rule) =
self.try_merge_qualified_rules(prev_rule, qualified_rule)
@ -530,7 +537,7 @@ impl Compressor {
)) if prev_rule.is_some() => {
if let Some(ComponentValue::StyleBlock(box StyleBlock::QualifiedRule(
box prev_rule,
))) = &prev_rule
))) = &mut prev_rule
{
if let Some(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 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 $@