Skip to content

Commit

Permalink
perf(css/codegen): Reduce allocations (#6599)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 committed Dec 8, 2022
1 parent 6fadb48 commit 538d63e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
6 changes: 3 additions & 3 deletions crates/swc_css_codegen/src/lib.rs
Expand Up @@ -2,7 +2,7 @@
#![allow(clippy::needless_update)]

pub use std::fmt::Result;
use std::{str, str::from_utf8};
use std::{borrow::Cow, str, str::from_utf8};

use serde::{Deserialize, Serialize};
use swc_atoms::*;
Expand Down Expand Up @@ -1565,9 +1565,9 @@ where
fn emit_ident(&mut self, n: &Ident) -> Result {
if self.config.minify {
let value = if self.ctx.allow_to_lowercase && self.config.minify {
n.value.to_ascii_lowercase().to_string()
Cow::Owned(n.value.to_ascii_lowercase())
} else {
n.value.to_string()
Cow::Borrowed(&n.value)
};
let serialized = serialize_ident(&value, n.raw.as_deref(), true);

Expand Down
53 changes: 49 additions & 4 deletions crates/swc_css_utils/src/lib.rs
@@ -1,6 +1,6 @@
#![deny(clippy::all)]

use std::{char::REPLACEMENT_CHARACTER, str};
use std::{borrow::Cow, char::REPLACEMENT_CHARACTER, str};

use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -153,8 +153,53 @@ pub static NAMED_COLORS: Lazy<AHashMap<JsWord, NamedColor>> = Lazy::new(|| {
named_colors
});

#[inline]
fn is_escape_not_required(value: &str, raw: Option<&str>) -> bool {
if value.is_empty() {
return true;
}

if (b'0'..=b'9').contains(&value.as_bytes()[0]) {
return false;
}

if value.len() == 1 && value.as_bytes()[0] == b'-' {
return false;
}

if value.len() >= 2
&& value.as_bytes()[0] == b'-'
&& (b'0'..=b'9').contains(&value.as_bytes()[1])
{
return false;
}

value.chars().all(|c| {
match c {
REPLACEMENT_CHARACTER if raw.is_some() => false,
'\x00' => false,
'\x01'..='\x1f' | '\x7F' => false,
'-' | '_' => true,
_ if !c.is_ascii()
|| c.is_ascii_digit()
|| c.is_ascii_uppercase()
|| c.is_ascii_lowercase() =>
{
true
}
// Otherwise, the escaped character.
_ => false,
}
})
}

// https://drafts.csswg.org/cssom/#serialize-an-identifier
pub fn serialize_ident(value: &str, raw: Option<&str>, minify: bool) -> String {
pub fn serialize_ident<'a>(value: &'a str, raw: Option<&str>, minify: bool) -> Cow<'a, str> {
// Fast-path
if is_escape_not_required(value, raw) {
return Cow::Borrowed(value);
}

let mut result = String::with_capacity(value.len());

//
Expand All @@ -175,7 +220,7 @@ pub fn serialize_ident(value: &str, raw: Option<&str>, minify: bool) -> String {
REPLACEMENT_CHARACTER if raw.is_some() => {
result.push_str(raw.unwrap());

return result;
return Cow::Owned(result);
}
// If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).
'\x00' => {
Expand Down Expand Up @@ -225,7 +270,7 @@ pub fn serialize_ident(value: &str, raw: Option<&str>, minify: bool) -> String {
}
}

result
Cow::Owned(result)
}

// https://github.com/servo/rust-cssparser/blob/4c5d065798ea1be649412532bde481dbd404f44a/src/serializer.rs#L166
Expand Down

1 comment on commit 538d63e

@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: 538d63e Previous: fe0c651 Ratio
es/full/bugs-1 288109 ns/iter (± 4895) 247101 ns/iter (± 22172) 1.17
es/full/minify/libraries/antd 1658905431 ns/iter (± 22417593) 1760932785 ns/iter (± 35236413) 0.94
es/full/minify/libraries/d3 318610130 ns/iter (± 9834903) 339077097 ns/iter (± 16890319) 0.94
es/full/minify/libraries/echarts 1287399654 ns/iter (± 14320181) 1361906932 ns/iter (± 72991969) 0.95
es/full/minify/libraries/jquery 98333338 ns/iter (± 668039) 100339372 ns/iter (± 3357304) 0.98
es/full/minify/libraries/lodash 109274037 ns/iter (± 1012557) 119202831 ns/iter (± 2226784) 0.92
es/full/minify/libraries/moment 54381016 ns/iter (± 347877) 55197044 ns/iter (± 1642735) 0.99
es/full/minify/libraries/react 20297218 ns/iter (± 205701) 21583706 ns/iter (± 747539) 0.94
es/full/minify/libraries/terser 251371063 ns/iter (± 3680202) 246785443 ns/iter (± 9590666) 1.02
es/full/minify/libraries/three 445172704 ns/iter (± 12340627) 489853108 ns/iter (± 18130568) 0.91
es/full/minify/libraries/typescript 2957533439 ns/iter (± 17379360) 3194478726 ns/iter (± 101831252) 0.93
es/full/minify/libraries/victory 637074385 ns/iter (± 7165648) 697338669 ns/iter (± 52703004) 0.91
es/full/minify/libraries/vue 132348143 ns/iter (± 1133625) 141988357 ns/iter (± 3318648) 0.93
es/full/codegen/es3 28047 ns/iter (± 42) 27717 ns/iter (± 142) 1.01
es/full/codegen/es5 27980 ns/iter (± 34) 27679 ns/iter (± 163) 1.01
es/full/codegen/es2015 28023 ns/iter (± 41) 27760 ns/iter (± 102) 1.01
es/full/codegen/es2016 28088 ns/iter (± 296) 27682 ns/iter (± 138) 1.01
es/full/codegen/es2017 27802 ns/iter (± 133) 27759 ns/iter (± 92) 1.00
es/full/codegen/es2018 28034 ns/iter (± 119) 27768 ns/iter (± 63) 1.01
es/full/codegen/es2019 28061 ns/iter (± 48) 27766 ns/iter (± 102) 1.01
es/full/codegen/es2020 28078 ns/iter (± 63) 27626 ns/iter (± 298) 1.02
es/full/all/es3 168974847 ns/iter (± 3049018) 172072617 ns/iter (± 6135596) 0.98
es/full/all/es5 159224910 ns/iter (± 4445343) 164746858 ns/iter (± 3252532) 0.97
es/full/all/es2015 118923272 ns/iter (± 1614307) 120140578 ns/iter (± 3531817) 0.99
es/full/all/es2016 118274144 ns/iter (± 452629) 120912820 ns/iter (± 2749116) 0.98
es/full/all/es2017 117735153 ns/iter (± 1429708) 123700056 ns/iter (± 3375730) 0.95
es/full/all/es2018 116493988 ns/iter (± 2347512) 123079663 ns/iter (± 3579266) 0.95
es/full/all/es2019 116407678 ns/iter (± 1954693) 119629726 ns/iter (± 4892562) 0.97
es/full/all/es2020 109606417 ns/iter (± 2048834) 115559026 ns/iter (± 2752948) 0.95
es/full/parser 522436 ns/iter (± 7735) 491022 ns/iter (± 14057) 1.06
es/full/base/fixer 22079 ns/iter (± 42) 22526 ns/iter (± 76) 0.98
es/full/base/resolver_and_hygiene 77693 ns/iter (± 72) 77989 ns/iter (± 1069) 1.00
serialization of ast node 140 ns/iter (± 0) 140 ns/iter (± 0) 1
serialization of serde 122 ns/iter (± 0) 122 ns/iter (± 0) 1
css/minify/libraries/bootstrap 28090871 ns/iter (± 202600) 28523506 ns/iter (± 207393) 0.98
css/visitor/compare/clone 2349046 ns/iter (± 17505) 2326696 ns/iter (± 12184) 1.01
css/visitor/compare/visit_mut_span 2559065 ns/iter (± 29445) 2436226 ns/iter (± 18097) 1.05
css/visitor/compare/visit_mut_span_panic 2570510 ns/iter (± 11764) 2496566 ns/iter (± 34891) 1.03
css/visitor/compare/fold_span 3502784 ns/iter (± 12368) 3464228 ns/iter (± 6354) 1.01
css/visitor/compare/fold_span_panic 3663065 ns/iter (± 55758) 3612309 ns/iter (± 22222) 1.01
css/lexer/bootstrap_5_1_3 5344480 ns/iter (± 855) 5337641 ns/iter (± 12562) 1.00
css/lexer/foundation_6_7_4 4498239 ns/iter (± 1115) 4479110 ns/iter (± 16889) 1.00
css/lexer/tailwind_3_1_1 857326 ns/iter (± 278) 851944 ns/iter (± 332) 1.01
css/parser/bootstrap_5_1_3 21381131 ns/iter (± 111391) 21381403 ns/iter (± 163550) 1.00
css/parser/foundation_6_7_4 17068300 ns/iter (± 97840) 16854198 ns/iter (± 92005) 1.01
css/parser/tailwind_3_1_1 3235680 ns/iter (± 5498) 3245862 ns/iter (± 7283) 1.00
es/codegen/colors 322507 ns/iter (± 180028) 321185 ns/iter (± 180106) 1.00
es/codegen/large 1222879 ns/iter (± 641167) 1229183 ns/iter (± 645421) 0.99
es/codegen/with-parser/colors 45513 ns/iter (± 458) 45411 ns/iter (± 326) 1.00
es/codegen/with-parser/large 511292 ns/iter (± 1323) 509123 ns/iter (± 2138) 1.00
es/minify/libraries/antd 1380441326 ns/iter (± 28462492) 1517962809 ns/iter (± 36952138) 0.91
es/minify/libraries/d3 293289030 ns/iter (± 6368591) 309231302 ns/iter (± 19307079) 0.95
es/minify/libraries/echarts 1192567859 ns/iter (± 3595429) 1257510887 ns/iter (± 72389710) 0.95
es/minify/libraries/jquery 91388606 ns/iter (± 1036557) 90566836 ns/iter (± 2785905) 1.01
es/minify/libraries/lodash 105456454 ns/iter (± 1145797) 100578361 ns/iter (± 3199530) 1.05
es/minify/libraries/moment 50436507 ns/iter (± 449051) 49917140 ns/iter (± 1056712) 1.01
es/minify/libraries/react 18719130 ns/iter (± 234495) 18060826 ns/iter (± 386015) 1.04
es/minify/libraries/terser 240405587 ns/iter (± 3793754) 229373188 ns/iter (± 5990438) 1.05
es/minify/libraries/three 417417340 ns/iter (± 3627354) 403579271 ns/iter (± 11867873) 1.03
es/minify/libraries/typescript 2688716784 ns/iter (± 9807572) 2812452288 ns/iter (± 89376664) 0.96
es/minify/libraries/victory 629532001 ns/iter (± 6737812) 592250630 ns/iter (± 49024942) 1.06
es/minify/libraries/vue 126997913 ns/iter (± 1385775) 124860179 ns/iter (± 7377630) 1.02
es/visitor/compare/clone 2664098 ns/iter (± 14823) 2429636 ns/iter (± 23865) 1.10
es/visitor/compare/visit_mut_span 3053377 ns/iter (± 25974) 2855607 ns/iter (± 12819) 1.07
es/visitor/compare/visit_mut_span_panic 3126956 ns/iter (± 27641) 2879966 ns/iter (± 29980) 1.09
es/visitor/compare/fold_span 4233110 ns/iter (± 28701) 3967326 ns/iter (± 25134) 1.07
es/visitor/compare/fold_span_panic 4494836 ns/iter (± 45068) 4088293 ns/iter (± 29642) 1.10
es/lexer/colors 17425 ns/iter (± 5) 17471 ns/iter (± 28) 1.00
es/lexer/angular 8218622 ns/iter (± 2952) 8216823 ns/iter (± 21759) 1.00
es/lexer/backbone 1072072 ns/iter (± 200) 1072300 ns/iter (± 5358) 1.00
es/lexer/jquery 5956012 ns/iter (± 1670) 5960605 ns/iter (± 10842) 1.00
es/lexer/jquery mobile 9178182 ns/iter (± 2037) 9183822 ns/iter (± 46051) 1.00
es/lexer/mootools 4686438 ns/iter (± 1974) 4670205 ns/iter (± 19861) 1.00
es/lexer/underscore 894340 ns/iter (± 392) 891591 ns/iter (± 7720) 1.00
es/lexer/three 27864260 ns/iter (± 19106) 27754705 ns/iter (± 131608) 1.00
es/lexer/yui 5046013 ns/iter (± 52261) 5057994 ns/iter (± 8886) 1.00
es/parser/colors 31005 ns/iter (± 182) 31417 ns/iter (± 195) 0.99
es/parser/angular 16696569 ns/iter (± 416873) 15862576 ns/iter (± 479840) 1.05
es/parser/backbone 2296871 ns/iter (± 13173) 2313100 ns/iter (± 11515) 0.99
es/parser/jquery 12349606 ns/iter (± 100460) 12024055 ns/iter (± 104950) 1.03
es/parser/jquery mobile 19328517 ns/iter (± 128731) 19919517 ns/iter (± 658234) 0.97
es/parser/mootools 9444402 ns/iter (± 29999) 9525641 ns/iter (± 48876) 0.99
es/parser/underscore 1943307 ns/iter (± 13648) 1888921 ns/iter (± 41464) 1.03
es/parser/three 57203964 ns/iter (± 891518) 54600402 ns/iter (± 1741517) 1.05
es/parser/yui 9567365 ns/iter (± 55568) 9347880 ns/iter (± 162241) 1.02
es/preset-env/usage/builtin_type 141257 ns/iter (± 32264) 140560 ns/iter (± 33798) 1.00
es/preset-env/usage/property 21592 ns/iter (± 37) 20563 ns/iter (± 328) 1.05
es/resolver/typescript 109847870 ns/iter (± 5445799) 122006933 ns/iter (± 3568118) 0.90
es/fixer/typescript 85626579 ns/iter (± 755695) 99501167 ns/iter (± 1962001) 0.86
es/hygiene/typescript 167863914 ns/iter (± 1988619) 198746705 ns/iter (± 4525290) 0.84
es/resolver_with_hygiene/typescript 298084476 ns/iter (± 4993842) 331304414 ns/iter (± 4293507) 0.90
es/visitor/base-perf/module_clone 74800 ns/iter (± 1355) 74446 ns/iter (± 1288) 1.00
es/visitor/base-perf/fold_empty 87601 ns/iter (± 1719) 85902 ns/iter (± 956) 1.02
es/visitor/base-perf/fold_noop_impl_all 87097 ns/iter (± 1210) 86065 ns/iter (± 942) 1.01
es/visitor/base-perf/fold_noop_impl_vec 86646 ns/iter (± 816) 85928 ns/iter (± 1419) 1.01
es/visitor/base-perf/boxing_boxed_clone 54 ns/iter (± 0) 54 ns/iter (± 0) 1
es/visitor/base-perf/boxing_unboxed_clone 58 ns/iter (± 0) 58 ns/iter (± 0) 1
es/visitor/base-perf/boxing_boxed 99 ns/iter (± 0) 99 ns/iter (± 0) 1
es/visitor/base-perf/boxing_unboxed 101 ns/iter (± 0) 101 ns/iter (± 0) 1
es/visitor/base-perf/visit_contains_this 3596 ns/iter (± 70) 3523 ns/iter (± 82) 1.02
es/base/parallel/resolver/typescript 10064820431 ns/iter (± 191299337) 9429015352 ns/iter (± 173604627) 1.07
es/base/parallel/hygiene/typescript 1146833684 ns/iter (± 21325446) 1258004048 ns/iter (± 25596301) 0.91
misc/visitors/time-complexity/time 5 94 ns/iter (± 0) 96 ns/iter (± 0) 0.98
misc/visitors/time-complexity/time 10 309 ns/iter (± 1) 315 ns/iter (± 3) 0.98
misc/visitors/time-complexity/time 15 667 ns/iter (± 7) 649 ns/iter (± 7) 1.03
misc/visitors/time-complexity/time 20 1223 ns/iter (± 6) 1191 ns/iter (± 9) 1.03
misc/visitors/time-complexity/time 40 6162 ns/iter (± 83) 6093 ns/iter (± 75) 1.01
misc/visitors/time-complexity/time 60 15578 ns/iter (± 37) 15117 ns/iter (± 114) 1.03
es/full-target/es2016 185568 ns/iter (± 1885) 180705 ns/iter (± 2689) 1.03
es/full-target/es2017 177114 ns/iter (± 1142) 176324 ns/iter (± 2402) 1.00
es/full-target/es2018 164399 ns/iter (± 773) 164561 ns/iter (± 1938) 1.00
es2020_nullish_coalescing 63691 ns/iter (± 512) 63778 ns/iter (± 592) 1.00
es2020_optional_chaining 91541 ns/iter (± 5922) 93065 ns/iter (± 654) 0.98
es2022_class_properties 89289 ns/iter (± 663) 89926 ns/iter (± 864) 0.99
es2018_object_rest_spread 68352 ns/iter (± 503) 69125 ns/iter (± 551) 0.99
es2019_optional_catch_binding 58238 ns/iter (± 548) 58342 ns/iter (± 625) 1.00
es2017_async_to_generator 59738 ns/iter (± 134) 58821 ns/iter (± 791) 1.02
es2016_exponentiation 61882 ns/iter (± 349) 62201 ns/iter (± 692) 0.99
es2015_arrow 66569 ns/iter (± 391) 67458 ns/iter (± 649) 0.99
es2015_block_scoped_fn 62498 ns/iter (± 454) 62615 ns/iter (± 896) 1.00
es2015_block_scoping 152813 ns/iter (± 9498) 147939 ns/iter (± 7286) 1.03
es2015_classes 111400 ns/iter (± 727) 112943 ns/iter (± 1241) 0.99
es2015_computed_props 58023 ns/iter (± 455) 58497 ns/iter (± 559) 0.99
es2015_destructuring 111300 ns/iter (± 303) 111699 ns/iter (± 1276) 1.00
es2015_duplicate_keys 61158 ns/iter (± 626) 61215 ns/iter (± 415) 1.00
es2015_parameters 75120 ns/iter (± 635) 75066 ns/iter (± 759) 1.00
es2015_fn_name 63025 ns/iter (± 734) 62692 ns/iter (± 952) 1.01
es2015_for_of 60551 ns/iter (± 316) 61230 ns/iter (± 922) 0.99
es2015_instanceof 59771 ns/iter (± 590) 60692 ns/iter (± 236) 0.98
es2015_shorthand_property 58657 ns/iter (± 604) 58221 ns/iter (± 688) 1.01
es2015_spread 58686 ns/iter (± 782) 58955 ns/iter (± 439) 1.00
es2015_sticky_regex 60288 ns/iter (± 254) 60110 ns/iter (± 465) 1.00
es2015_typeof_symbol 60416 ns/iter (± 246) 59018 ns/iter (± 539) 1.02
es/transform/baseline/base 50143 ns/iter (± 147) 48590 ns/iter (± 540) 1.03
es/transform/baseline/common_reserved_word 60064 ns/iter (± 257) 60069 ns/iter (± 802) 1.00
es/transform/baseline/common_typescript 139169 ns/iter (± 1371) 140010 ns/iter (± 3438) 0.99
es/target/es3 164814 ns/iter (± 907) 162896 ns/iter (± 2399) 1.01
es/target/es2015 614038 ns/iter (± 3717) 610624 ns/iter (± 7554) 1.01
es/target/es2016 62071 ns/iter (± 294) 63161 ns/iter (± 506) 0.98
es/target/es2017 58906 ns/iter (± 459) 59721 ns/iter (± 213) 0.99
es/target/es2018 78729 ns/iter (± 531) 78286 ns/iter (± 961) 1.01
es/target/es2020 128230 ns/iter (± 777) 126979 ns/iter (± 1136) 1.01
babelify-only 673521 ns/iter (± 1641) 645767 ns/iter (± 7142) 1.04
parse_and_babelify_angular 36318324 ns/iter (± 462570) 39541609 ns/iter (± 723076) 0.92
parse_and_babelify_backbone 5482930 ns/iter (± 53987) 5475736 ns/iter (± 87356) 1.00
parse_and_babelify_jquery 30050412 ns/iter (± 276999) 30733920 ns/iter (± 462320) 0.98
parse_and_babelify_jquery_mobile 49779526 ns/iter (± 571360) 51658992 ns/iter (± 898572) 0.96
parse_and_babelify_mootools 32073968 ns/iter (± 536301) 34012744 ns/iter (± 959493) 0.94
parse_and_babelify_underscore 4443885 ns/iter (± 14174) 4494157 ns/iter (± 38382) 0.99
parse_and_babelify_yui 30014828 ns/iter (± 530249) 31759027 ns/iter (± 1157393) 0.95
html/minify/document/css_spec 41781682 ns/iter (± 365973) 43258485 ns/iter (± 533672) 0.97
html/minify/document/github 17938377 ns/iter (± 80765) 18099139 ns/iter (± 256760) 0.99
html/minify/document/stackoverflow 15918116 ns/iter (± 162740) 16217296 ns/iter (± 143809) 0.98
html/minify/document_fragment/css_spec 40262307 ns/iter (± 356042) 40687850 ns/iter (± 711470) 0.99
html/minify/document_fragment/github 17340529 ns/iter (± 76117) 17247325 ns/iter (± 198800) 1.01
html/minify/document_fragment/stackoverflow 15280068 ns/iter (± 103086) 15451898 ns/iter (± 196944) 0.99
html/document/visitor/compare/clone 336447 ns/iter (± 2773) 337016 ns/iter (± 3728) 1.00
html/document/visitor/compare/visit_mut_span 364490 ns/iter (± 3098) 365432 ns/iter (± 4191) 1.00
html/document/visitor/compare/visit_mut_span_panic 371523 ns/iter (± 3507) 373385 ns/iter (± 4329) 1.00
html/document/visitor/compare/fold_span 402936 ns/iter (± 2914) 399453 ns/iter (± 3385) 1.01
html/document/visitor/compare/fold_span_panic 450981 ns/iter (± 2620) 452444 ns/iter (± 5134) 1.00
html/document_fragment/visitor/compare/clone 338431 ns/iter (± 2403) 329264 ns/iter (± 3370) 1.03
html/document_fragment/visitor/compare/visit_mut_span 364496 ns/iter (± 2296) 353785 ns/iter (± 4981) 1.03
html/document_fragment/visitor/compare/visit_mut_span_panic 368140 ns/iter (± 1917) 366547 ns/iter (± 2888) 1.00
html/document_fragment/visitor/compare/fold_span 403566 ns/iter (± 3122) 392677 ns/iter (± 2764) 1.03
html/document_fragment/visitor/compare/fold_span_panic 461691 ns/iter (± 3581) 449964 ns/iter (± 3274) 1.03
html/lexer/css_2021_spec 15216102 ns/iter (± 73767) 15023146 ns/iter (± 153722) 1.01
html/lexer/github_com_17_05_2022 5910938 ns/iter (± 44757) 5873897 ns/iter (± 44254) 1.01
html/lexer/stackoverflow_com_17_05_2022 5543848 ns/iter (± 41953) 5544854 ns/iter (± 53234) 1.00
html/parser/parser_document/css_2021_spec 24818878 ns/iter (± 204225) 25211606 ns/iter (± 243436) 0.98
html/parser/parser_document/github_com_17_05_2022 8566891 ns/iter (± 45465) 8549066 ns/iter (± 107589) 1.00
html/parser/parser_document/stackoverflow_com_17_05_2022 7608899 ns/iter (± 56367) 7549404 ns/iter (± 81031) 1.01
html/parser/parser_document_fragment/css_2021_spec 25273256 ns/iter (± 143515) 25123178 ns/iter (± 415398) 1.01
html/parser/parser_document_fragment/github_com_17_05_2022 8600222 ns/iter (± 68371) 8546638 ns/iter (± 115978) 1.01
html/parser/parser_document_fragment/stackoverflow_com_17_05_2022 7686886 ns/iter (± 33559) 7534413 ns/iter (± 77134) 1.02

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

Please sign in to comment.