Skip to content

Commit

Permalink
perf(css/ast): Use Atom for raw values (#6401)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Nov 11, 2022
1 parent e5ad5e5 commit ec2c021
Show file tree
Hide file tree
Showing 165 changed files with 1,624 additions and 1,820 deletions.
5 changes: 2 additions & 3 deletions crates/swc_css_ast/src/at_rule.rs
@@ -1,6 +1,6 @@
use is_macro::Is;
use string_enum::StringEnum;
use swc_atoms::JsWord;
use swc_atoms::{Atom, JsWord};
use swc_common::{ast_node, EqIgnoreSpan, Span};

use crate::{
Expand Down Expand Up @@ -809,8 +809,7 @@ pub struct ExtensionName {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl EqIgnoreSpan for ExtensionName {
Expand Down
11 changes: 4 additions & 7 deletions crates/swc_css_ast/src/selector.rs
@@ -1,6 +1,6 @@
use is_macro::Is;
use string_enum::StringEnum;
use swc_atoms::JsWord;
use swc_atoms::{Atom, JsWord};
use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};

use crate::{Delimiter, Ident, ListOfComponentValues, Str, TokenAndSpan};
Expand Down Expand Up @@ -369,11 +369,9 @@ pub enum AnPlusB {
pub struct AnPlusBNotation {
pub span: Span,
pub a: Option<i32>,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub a_raw: Option<JsWord>,
pub a_raw: Option<Atom>,
pub b: Option<i32>,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub b_raw: Option<JsWord>,
pub b_raw: Option<Atom>,
}

#[ast_node("PseudoElementSelector")]
Expand Down Expand Up @@ -403,8 +401,7 @@ pub struct CustomHighlightName {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl EqIgnoreSpan for CustomHighlightName {
Expand Down
47 changes: 16 additions & 31 deletions crates/swc_css_ast/src/token.rs
Expand Up @@ -5,7 +5,7 @@ use std::{

use is_macro::Is;
use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_atoms::{Atom, JsWord};
use swc_common::{ast_node, EqIgnoreSpan, Span};

#[ast_node("PreservedToken")]
Expand Down Expand Up @@ -52,65 +52,55 @@ pub enum Token {
Ident {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw: JsWord,
raw: Atom,
},

Function {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw: JsWord,
raw: Atom,
},

/// `@`
AtKeyword {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw: JsWord,
raw: Atom,
},

/// `#`
Hash {
is_id: bool,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw: JsWord,
raw: Atom,
},

String {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw: JsWord,
raw: Atom,
},

BadString {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw_value: JsWord,
raw_value: Atom,
},

/// `url(value)`
Url {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
name: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw_name: JsWord,
raw_name: Atom,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw_value: JsWord,
raw_value: Atom,
},

BadUrl {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
name: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw_name: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw_value: JsWord,
raw_name: Atom,
raw_value: Atom,
},

Delim {
Expand All @@ -119,34 +109,29 @@ pub enum Token {

Number {
value: f64,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw: JsWord,
raw: Atom,
#[serde(rename = "type")]
type_flag: NumberType,
},

Percentage {
value: f64,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw: JsWord,
raw: Atom,
},

Dimension {
value: f64,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw_value: JsWord,
raw_value: Atom,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
unit: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
raw_unit: JsWord,
raw_unit: Atom,
#[serde(rename = "type")]
type_flag: NumberType,
},

/// One or more whitespace.
WhiteSpace {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
value: JsWord,
value: Atom,
},

/// `<!--`
Expand Down
29 changes: 10 additions & 19 deletions crates/swc_css_ast/src/value.rs
Expand Up @@ -5,7 +5,7 @@ use std::{

use is_macro::Is;
use string_enum::StringEnum;
use swc_atoms::JsWord;
use swc_atoms::{Atom, JsWord};
use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};

use crate::Function;
Expand All @@ -16,8 +16,7 @@ pub struct Ident {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl EqIgnoreSpan for Ident {
Expand All @@ -42,8 +41,7 @@ pub struct CustomIdent {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl EqIgnoreSpan for CustomIdent {
Expand All @@ -58,8 +56,7 @@ pub struct DashedIdent {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl EqIgnoreSpan for DashedIdent {
Expand All @@ -74,8 +71,7 @@ pub struct CustomPropertyName {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl EqIgnoreSpan for CustomPropertyName {
Expand All @@ -91,8 +87,7 @@ pub struct Str {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl EqIgnoreSpan for Str {
Expand Down Expand Up @@ -164,8 +159,7 @@ pub struct HexColor {
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
/// Does **not** include `#`
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

#[ast_node]
Expand Down Expand Up @@ -326,8 +320,7 @@ pub enum TimePercentage {
pub struct Integer {
pub span: Span,
pub value: i64,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl EqIgnoreSpan for Integer {
Expand All @@ -340,8 +333,7 @@ impl EqIgnoreSpan for Integer {
pub struct Number {
pub span: Span,
pub value: f64,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

impl Eq for Number {}
Expand Down Expand Up @@ -431,8 +423,7 @@ pub struct UrlValueRaw {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub value: JsWord,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
pub raw: Option<JsWord>,
pub raw: Option<Atom>,
}

#[ast_node]
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_css_codegen/src/lib.rs
Expand Up @@ -376,7 +376,7 @@ where
AtRuleName::Ident(swc_css_ast::Ident {
span: n.span,
value: js_word!("layer"),
raw: Some(js_word!("layer"))
raw: None
})
)
}
Expand Down
16 changes: 12 additions & 4 deletions crates/swc_css_minifier/src/compressor/mod.rs
Expand Up @@ -400,14 +400,22 @@ impl VisitMut for Compressor {
| Token::Function { value, .. }
| Token::AtKeyword { value, .. }
| Token::String { value, .. }
| Token::BadString {
raw_value: value, ..
}
| Token::Dimension { unit: value, .. }
| Token::Url { value, .. }
if !contains_only_ascii_characters(value) =>
{
self.need_utf8_at_rule = true;
}
Token::BadString {
raw_value: value, ..
}
| Token::BadUrl {
raw_value: value, ..
} if !contains_only_ascii_characters(value) => {
self.need_utf8_at_rule = true;
}
Token::Dimension { unit: value, .. } if !contains_only_ascii_characters(value) => {
self.need_utf8_at_rule = true;
}
_ => {}
}
}
Expand Down
21 changes: 10 additions & 11 deletions crates/swc_css_parser/src/lexer/mod.rs
@@ -1,6 +1,6 @@
use std::{cell::RefCell, char::REPLACEMENT_CHARACTER, rc::Rc};

use swc_atoms::{js_word, JsWord};
use swc_atoms::{js_word, Atom, JsWord};
use swc_common::{input::Input, BytePos, Span};
use swc_css_ast::{NumberType, Token, TokenAndSpan};

Expand Down Expand Up @@ -559,9 +559,9 @@ where
// unit set initially to the empty string.
let mut token = Token::Dimension {
value: number.0,
raw_value: number.1.into(),
raw_value: number.1,
unit: js_word!(""),
raw_unit: js_word!(""),
raw_unit: "".into(),
type_flag: number.2,
};

Expand Down Expand Up @@ -592,15 +592,15 @@ where

return Ok(Token::Percentage {
value: number.0,
raw: number.1.into(),
raw: number.1,
});
}

// Otherwise, create a <number-token> with the same value and type flag as
// number, and return it.
Ok(Token::Number {
value: number.0,
raw: number.1.into(),
raw: number.1,
type_flag: number.2,
})
}
Expand Down Expand Up @@ -779,7 +779,7 @@ where

// This section describes how to consume a url token from a stream of code
// points. It returns either a <url-token> or a <bad-url-token>.
fn read_url(&mut self, name: (JsWord, JsWord), before: String) -> LexResult<Token> {
fn read_url(&mut self, name: (JsWord, Atom), before: String) -> LexResult<Token> {
// Initially create a <url-token> with its value set to the empty string.
self.with_buf_and_raw_buf(|l, out, raw| {
raw.push_str(&before);
Expand Down Expand Up @@ -1178,7 +1178,7 @@ where
// This section describes how to consume an ident sequence from a stream of code
// points. It returns a string containing the largest name that can be formed
// from adjacent code points in the stream, starting from the first.
fn read_ident_sequence(&mut self) -> LexResult<(JsWord, JsWord)> {
fn read_ident_sequence(&mut self) -> LexResult<(JsWord, Atom)> {
self.with_buf_and_raw_buf(|l, buf, raw| {
// Let result initially be an empty string.
// Done above
Expand Down Expand Up @@ -1219,10 +1219,9 @@ where

// This section describes how to consume a number from a stream of code points.
// It returns a numeric value, and a type which is either "integer" or "number".
fn read_number(&mut self) -> LexResult<(f64, String, NumberType)> {
let parsed =
fn read_number(&mut self) -> LexResult<(f64, Atom, NumberType)> {
let parsed: (Atom, NumberType) = self.with_buf(|l, out| {
// Initially set type to "integer". Let repr be the empty string.
self.with_buf(|l, out| {
let mut type_flag = NumberType::Integer;

// If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS
Expand Down Expand Up @@ -1324,7 +1323,7 @@ where
})?;

// Convert repr to a number, and set the value to the returned value.
let value = lexical::parse(&parsed.0).unwrap_or_else(|err| {
let value = lexical::parse(&*parsed.0).unwrap_or_else(|err| {
unreachable!("failed to parse `{}` using lexical: {:?}", parsed.0, err)
});

Expand Down

1 comment on commit ec2c021

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: ec2c021 Previous: 574502a Ratio
es/full/bugs-1 334786 ns/iter (± 16748) 342849 ns/iter (± 41711) 0.98
es/full/minify/libraries/antd 1824535495 ns/iter (± 35894667) 1849686838 ns/iter (± 49179473) 0.99
es/full/minify/libraries/d3 408326702 ns/iter (± 26978303) 423679509 ns/iter (± 23543023) 0.96
es/full/minify/libraries/echarts 1552193114 ns/iter (± 20086071) 1550138874 ns/iter (± 69677661) 1.00
es/full/minify/libraries/jquery 99772654 ns/iter (± 1004242) 101225832 ns/iter (± 1652205) 0.99
es/full/minify/libraries/lodash 139744559 ns/iter (± 7001730) 115895899 ns/iter (± 3760431) 1.21
es/full/minify/libraries/moment 60782910 ns/iter (± 2667101) 58812675 ns/iter (± 4418008) 1.03
es/full/minify/libraries/react 20541130 ns/iter (± 831642) 19846156 ns/iter (± 428110) 1.04
es/full/minify/libraries/terser 316565708 ns/iter (± 24688809) 291308614 ns/iter (± 11540782) 1.09
es/full/minify/libraries/three 575697083 ns/iter (± 27222102) 537158095 ns/iter (± 5535730) 1.07
es/full/minify/libraries/typescript 3270780317 ns/iter (± 24562878) 3297559709 ns/iter (± 27349424) 0.99
es/full/minify/libraries/victory 798110882 ns/iter (± 15674171) 810724383 ns/iter (± 20774533) 0.98
es/full/minify/libraries/vue 151323074 ns/iter (± 5163757) 154261987 ns/iter (± 3503762) 0.98
es/full/codegen/es3 33110 ns/iter (± 2709) 32799 ns/iter (± 614) 1.01
es/full/codegen/es5 33108 ns/iter (± 1105) 32861 ns/iter (± 896) 1.01
es/full/codegen/es2015 32870 ns/iter (± 1052) 32944 ns/iter (± 1024) 1.00
es/full/codegen/es2016 33526 ns/iter (± 832) 33042 ns/iter (± 1493) 1.01
es/full/codegen/es2017 33418 ns/iter (± 604) 32856 ns/iter (± 493) 1.02
es/full/codegen/es2018 33606 ns/iter (± 359) 32961 ns/iter (± 659) 1.02
es/full/codegen/es2019 33648 ns/iter (± 703) 32829 ns/iter (± 833) 1.02
es/full/codegen/es2020 33647 ns/iter (± 823) 32866 ns/iter (± 900) 1.02
es/full/all/es3 189247676 ns/iter (± 5197430) 189071197 ns/iter (± 11157902) 1.00
es/full/all/es5 180338464 ns/iter (± 5069777) 178319800 ns/iter (± 6482341) 1.01
es/full/all/es2015 141966737 ns/iter (± 4502041) 145170523 ns/iter (± 6618842) 0.98
es/full/all/es2016 142717290 ns/iter (± 3849932) 144029821 ns/iter (± 5628687) 0.99
es/full/all/es2017 140641379 ns/iter (± 4392570) 144696980 ns/iter (± 9172301) 0.97
es/full/all/es2018 139091794 ns/iter (± 5812591) 139067163 ns/iter (± 6894041) 1.00
es/full/all/es2019 138970966 ns/iter (± 4446261) 140477494 ns/iter (± 7344222) 0.99
es/full/all/es2020 133953990 ns/iter (± 4780667) 135078652 ns/iter (± 4366346) 0.99
es/full/parser 694599 ns/iter (± 33529) 714607 ns/iter (± 41380) 0.97
es/full/base/fixer 26481 ns/iter (± 892) 26594 ns/iter (± 1643) 1.00
es/full/base/resolver_and_hygiene 90863 ns/iter (± 3283) 91512 ns/iter (± 4012) 0.99
serialization of ast node 213 ns/iter (± 5) 215 ns/iter (± 2) 0.99
serialization of serde 215 ns/iter (± 2) 211 ns/iter (± 3) 1.02

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.