Skip to content

Commit

Permalink
refactor(macros): Reduce compile time (#7132)
Browse files Browse the repository at this point in the history
**Description:**

 - Reduce usage of generics in proc-macros.
 - Remove needless operations like parsing tokens as an AST node.
  • Loading branch information
kdy1 committed Mar 23, 2023
1 parent d1ae6bb commit 2154a3f
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 102 deletions.
4 changes: 2 additions & 2 deletions crates/ast_node/src/enum_deserialize.rs
Expand Up @@ -29,7 +29,7 @@ pub fn expand(
data,
..
}: DeriveInput,
) -> Vec<ItemImpl> {
) -> ItemImpl {
let data = match data {
Data::Enum(data) => data,
_ => unreachable!("expand_enum is called with none-enum item"),
Expand Down Expand Up @@ -438,5 +438,5 @@ pub fn expand(
.with_generics(generics)
};

vec![deserialize]
deserialize
}
39 changes: 5 additions & 34 deletions crates/ast_node/src/lib.rs
Expand Up @@ -16,29 +16,18 @@ mod spanned;
#[proc_macro_derive(Spanned, attributes(span))]
pub fn derive_spanned(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse::<DeriveInput>(input).expect("failed to parse input as DeriveInput");
let name = input.ident.clone();

let item = self::spanned::derive(input);

print_item(
"derive(Spanned)",
&format!("IMPL_SPANNED_FOR_{}", name),
item.dump(),
)
print("derive(Spanned)", item.dump())
}

/// Derives `serde::Deserialize` which is aware of `tag` based deserialization.
#[proc_macro_derive(DeserializeEnum, attributes(tag))]
pub fn derive_deserialize_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse::<DeriveInput>(input).expect("failed to parse input as DeriveInput");

let item =
enum_deserialize::expand(input)
.into_iter()
.fold(TokenStream::new(), |mut t, item| {
item.to_tokens(&mut t);
t
});
let item = enum_deserialize::expand(input);

print("derive(DeserializeEnum)", item.dump())
}
Expand Down Expand Up @@ -143,7 +132,7 @@ pub fn ast_serde(
}
};

print("ast_serde", item)
print("ast_serde", item.into())
}

struct AddAttr;
Expand Down Expand Up @@ -307,31 +296,13 @@ pub fn ast_node(

if let Some(items) = ast_node_impl {
for item in items {
quote = quote.quote_with(smart_quote!(Vars { item }, { item }))
quote.push_tokens(&item);
}
}

quote
}
};

print("ast_node", item)
}

/// Workarounds https://github.com/rust-lang/rust/issues/44925
fn print_item<T: Into<TokenStream>>(
name: &'static str,
const_name: &str,
item: T,
) -> proc_macro::TokenStream {
let item = Quote::new(def_site::<Span>()).quote_with(smart_quote!(
Vars {
item: item.into(),
NAME: Ident::new(const_name, Span::call_site())
},
{
const NAME: () = { item };
}
));
print(name, item)
print("ast_node", item.into())
}
10 changes: 4 additions & 6 deletions crates/from_variant/src/lib.rs
@@ -1,6 +1,6 @@
extern crate proc_macro;

use pmutil::{smart_quote, Quote, ToTokensExt};
use pmutil::{smart_quote, Quote};
use swc_macros_common::prelude::*;
use syn::*;

Expand All @@ -17,7 +17,7 @@ pub fn derive_from_variant(input: proc_macro::TokenStream) -> proc_macro::TokenS
t
});

print("derive(FromVariant)", item.dump())
print("derive(FromVariant)", item)
}

fn derive(
Expand Down Expand Up @@ -62,7 +62,8 @@ fn derive(
}
}
))
.parse();
.parse::<ItemImpl>()
.with_generics(generics.clone());

from_impls.push(from_impl);
}
Expand All @@ -73,7 +74,4 @@ fn derive(
}

from_impls
.into_iter()
.map(|item| item.with_generics(generics.clone()))
.collect()
}
9 changes: 3 additions & 6 deletions crates/swc_macros_common/src/lib.rs
@@ -1,3 +1,5 @@
//! Internal crate for the swc project.

extern crate proc_macro;

#[cfg(procmacro2_semver_exempt)]
Expand Down Expand Up @@ -29,14 +31,9 @@ pub fn def_site<T: FromSpan>() -> T {
}

/// `attr` - tokens inside `#[]`. e.g. `derive(EqIgnoreSpan)`, ast_node
pub fn print<T: Into<proc_macro2::TokenStream>>(
attr: &'static str,
t: T,
) -> proc_macro::TokenStream {
pub fn print(attr: &'static str, tokens: proc_macro2::TokenStream) -> proc_macro::TokenStream {
use std::env;

let tokens = t.into();

match env::var("PRINT_GENERATED") {
Ok(ref s) if s == "1" || attr == s => {}
_ => return tokens.into(),
Expand Down
43 changes: 10 additions & 33 deletions crates/swc_macros_common/src/syn_ext.rs
@@ -1,4 +1,3 @@
use pmutil::ToTokensExt;
use quote::quote;
use syn::{punctuated::Pair, *};

Expand Down Expand Up @@ -60,46 +59,24 @@ impl ItemImplExt for ItemImpl {

// Handle generics defined on struct, enum, or union.
let mut item: ItemImpl = {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let item = if let Some((ref polarity, ref path, ref for_token)) = self.trait_ {
quote! {
impl #impl_generics #polarity #path #for_token #ty #ty_generics #where_clause {}
}
} else {
quote! {
impl #impl_generics #ty #ty_generics #where_clause {}

}
let (_, ty_generics, _) = generics.split_for_impl();
let item = quote! {
#ty #ty_generics
};
parse(item.dump().into())
.unwrap_or_else(|err| panic!("with_generics failed: {}\n{}", err, item.dump()))

ItemImpl {
generics,
self_ty: parse2(item).unwrap(),
..self
}
};

// Handle generics added by proc-macro.
item.generics
.params
.extend(self.generics.params.into_pairs());
match self.generics.where_clause {
Some(WhereClause {
ref mut predicates, ..
}) => predicates.extend(
generics
.where_clause
.into_iter()
.flat_map(|wc| wc.predicates.into_pairs()),
),
ref mut opt @ None => *opt = generics.where_clause,
}

ItemImpl {
attrs: self.attrs,
defaultness: self.defaultness,
unsafety: self.unsafety,
impl_token: self.impl_token,
brace_token: self.brace_token,
items: self.items,
..item
}
item
}
}

Expand Down
35 changes: 14 additions & 21 deletions crates/testing_macros/src/fixture.rs
Expand Up @@ -6,13 +6,13 @@ use std::{
use anyhow::{Context, Error};
use glob::glob;
use once_cell::sync::Lazy;
use pmutil::q;
use pmutil::{q, Quote};
use proc_macro2::Span;
use regex::Regex;
use relative_path::RelativePath;
use syn::{
parse::{Parse, ParseStream},
Ident, ItemFn, Lit, LitStr, Meta, NestedMeta, Token,
Ident, Lit, LitStr, Meta, NestedMeta, Token,
};

pub struct Config {
Expand Down Expand Up @@ -96,7 +96,7 @@ impl Parse for Config {
}
}

pub fn expand(callee: &Ident, attr: Config) -> Result<Vec<ItemFn>, Error> {
pub fn expand(callee: &Ident, attr: Config) -> Result<Vec<Quote>, Error> {
let base_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect(
"#[fixture] requires CARGO_MANIFEST_DIR because it's relative to cargo manifest directory",
));
Expand Down Expand Up @@ -152,39 +152,32 @@ pub fn expand(callee: &Ident, attr: Config) -> Result<Vec<ItemFn>, Error> {
.replace("___", "__");
let test_ident = Ident::new(&test_name, Span::call_site());

let mut f = q!(
let ignored_attr = if ignored {
q!(Vars {}, { #[ignore] })
} else {
Quote::new_call_site()
};

let f = q!(
Vars {
test_ident,
path_str: &abs_path.to_string_lossy(),
callee
callee,
ignored_attr,
},
{
#[test]
#[inline(never)]
#[ignore]
#[doc(hidden)]
#[allow(non_snake_case)]
ignored_attr
fn test_ident() {
eprintln!("Input: {}", path_str);

callee(::std::path::PathBuf::from(path_str));
}
}
)
.parse::<ItemFn>();

if !ignored {
f.attrs.retain(|attr| {
if let Some(name) = attr.path.get_ident() {
if name == "ignore" {
return false;
}
}

true
});
//
}
);

test_fns.push(f);
}
Expand Down

1 comment on commit 2154a3f

@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: 2154a3f Previous: dfe1a3f Ratio
es/full/bugs-1 308079 ns/iter (± 11298) 299338 ns/iter (± 12160) 1.03
es/full/minify/libraries/antd 1573873204 ns/iter (± 31829042) 1530115211 ns/iter (± 22055664) 1.03
es/full/minify/libraries/d3 304265851 ns/iter (± 4570805) 286425213 ns/iter (± 5395147) 1.06
es/full/minify/libraries/echarts 1208761978 ns/iter (± 14423995) 1158154835 ns/iter (± 18380567) 1.04
es/full/minify/libraries/jquery 91919029 ns/iter (± 897868) 88933628 ns/iter (± 832663) 1.03
es/full/minify/libraries/lodash 107104373 ns/iter (± 615446) 103476316 ns/iter (± 963530) 1.04
es/full/minify/libraries/moment 53480462 ns/iter (± 460800) 51822978 ns/iter (± 390190) 1.03
es/full/minify/libraries/react 19204611 ns/iter (± 182799) 18860386 ns/iter (± 133921) 1.02
es/full/minify/libraries/terser 246867678 ns/iter (± 4536248) 236310603 ns/iter (± 3340804) 1.04
es/full/minify/libraries/three 433418376 ns/iter (± 7376547) 418281429 ns/iter (± 6421719) 1.04
es/full/minify/libraries/typescript 2918953564 ns/iter (± 22342807) 2867710124 ns/iter (± 23607323) 1.02
es/full/minify/libraries/victory 639550056 ns/iter (± 17131163) 635776845 ns/iter (± 7474258) 1.01
es/full/minify/libraries/vue 130797811 ns/iter (± 1394357) 128648918 ns/iter (± 1868562) 1.02
es/full/codegen/es3 28444 ns/iter (± 98) 29011 ns/iter (± 37) 0.98
es/full/codegen/es5 28476 ns/iter (± 641) 29071 ns/iter (± 108) 0.98
es/full/codegen/es2015 28481 ns/iter (± 61) 28721 ns/iter (± 285) 0.99
es/full/codegen/es2016 28541 ns/iter (± 89) 28874 ns/iter (± 277) 0.99
es/full/codegen/es2017 28514 ns/iter (± 45) 28677 ns/iter (± 287) 0.99
es/full/codegen/es2018 28489 ns/iter (± 88) 28770 ns/iter (± 289) 0.99
es/full/codegen/es2019 28519 ns/iter (± 107) 29032 ns/iter (± 258) 0.98
es/full/codegen/es2020 28532 ns/iter (± 56) 29012 ns/iter (± 199) 0.98
es/full/all/es3 185192352 ns/iter (± 2517023) 181516665 ns/iter (± 2436416) 1.02
es/full/all/es5 176549765 ns/iter (± 2583559) 173602577 ns/iter (± 3464624) 1.02
es/full/all/es2015 139468511 ns/iter (± 3133645) 137590364 ns/iter (± 1567222) 1.01
es/full/all/es2016 138067402 ns/iter (± 3380487) 134337214 ns/iter (± 1447116) 1.03
es/full/all/es2017 136328419 ns/iter (± 1032058) 132406237 ns/iter (± 1994064) 1.03
es/full/all/es2018 133878531 ns/iter (± 1762895) 127966435 ns/iter (± 1983365) 1.05
es/full/all/es2019 131645550 ns/iter (± 1359029) 126490191 ns/iter (± 1786442) 1.04
es/full/all/es2020 121803165 ns/iter (± 1107716) 118710883 ns/iter (± 397802) 1.03
es/full/parser 542392 ns/iter (± 9277) 524403 ns/iter (± 9090) 1.03
es/full/base/fixer 22379 ns/iter (± 23) 21978 ns/iter (± 160) 1.02
es/full/base/resolver_and_hygiene 82714 ns/iter (± 129) 82210 ns/iter (± 579) 1.01
serialization of ast node 123 ns/iter (± 0) 123 ns/iter (± 0) 1
serialization of serde 128 ns/iter (± 0) 126 ns/iter (± 1) 1.02
css/minify/libraries/bootstrap 28431629 ns/iter (± 158058) 27980381 ns/iter (± 107003) 1.02
css/visitor/compare/clone 2112689 ns/iter (± 10470) 2054204 ns/iter (± 27558) 1.03
css/visitor/compare/visit_mut_span 2292726 ns/iter (± 5036) 2246346 ns/iter (± 9641) 1.02
css/visitor/compare/visit_mut_span_panic 2344065 ns/iter (± 3169) 2289427 ns/iter (± 16979) 1.02
css/visitor/compare/fold_span 3031914 ns/iter (± 17628) 3038809 ns/iter (± 30977) 1.00
css/visitor/compare/fold_span_panic 3160896 ns/iter (± 12614) 3135893 ns/iter (± 16670) 1.01
css/lexer/bootstrap_5_1_3 5162929 ns/iter (± 12064) 5050544 ns/iter (± 38395) 1.02
css/lexer/foundation_6_7_4 4345802 ns/iter (± 1549) 4264020 ns/iter (± 35343) 1.02
css/lexer/tailwind_3_1_1 824758 ns/iter (± 640) 804012 ns/iter (± 6722) 1.03
css/parser/bootstrap_5_1_3 22002007 ns/iter (± 146383) 21353661 ns/iter (± 103150) 1.03
css/parser/foundation_6_7_4 17521477 ns/iter (± 56423) 17258018 ns/iter (± 153604) 1.02
css/parser/tailwind_3_1_1 3359775 ns/iter (± 2308) 3307935 ns/iter (± 23661) 1.02
es/codegen/colors 330403 ns/iter (± 186450) 325653 ns/iter (± 183528) 1.01
es/codegen/large 1231069 ns/iter (± 629626) 1186953 ns/iter (± 606530) 1.04
es/codegen/with-parser/colors 48845 ns/iter (± 420) 47724 ns/iter (± 210) 1.02
es/codegen/with-parser/large 529520 ns/iter (± 1233) 519214 ns/iter (± 2890) 1.02
es/minify/libraries/antd 1369330087 ns/iter (± 20507861) 1313201326 ns/iter (± 13370580) 1.04
es/minify/libraries/d3 255177491 ns/iter (± 5228975) 244929442 ns/iter (± 1775034) 1.04
es/minify/libraries/echarts 1039117576 ns/iter (± 14801212) 979353645 ns/iter (± 9432930) 1.06
es/minify/libraries/jquery 79238484 ns/iter (± 427702) 76709294 ns/iter (± 637465) 1.03
es/minify/libraries/lodash 94766954 ns/iter (± 1101863) 91731419 ns/iter (± 815951) 1.03
es/minify/libraries/moment 45695352 ns/iter (± 312946) 44708116 ns/iter (± 203309) 1.02
es/minify/libraries/react 16995671 ns/iter (± 224623) 16764520 ns/iter (± 114239) 1.01
es/minify/libraries/terser 209332466 ns/iter (± 3821235) 200114929 ns/iter (± 941911) 1.05
es/minify/libraries/three 355621812 ns/iter (± 7955843) 337938084 ns/iter (± 4402559) 1.05
es/minify/libraries/typescript 2524374557 ns/iter (± 24837152) 2400982735 ns/iter (± 14377269) 1.05
es/minify/libraries/victory 565683693 ns/iter (± 7706162) 507667367 ns/iter (± 5053215) 1.11
es/minify/libraries/vue 116969694 ns/iter (± 1510526) 111340534 ns/iter (± 743384) 1.05
es/visitor/compare/clone 2324650 ns/iter (± 13628) 2276307 ns/iter (± 19092) 1.02
es/visitor/compare/visit_mut_span 2687402 ns/iter (± 7185) 2634171 ns/iter (± 8989) 1.02
es/visitor/compare/visit_mut_span_panic 2731974 ns/iter (± 3620) 2639557 ns/iter (± 13613) 1.04
es/visitor/compare/fold_span 3812717 ns/iter (± 6267) 3708498 ns/iter (± 23530) 1.03
es/visitor/compare/fold_span_panic 3967697 ns/iter (± 12378) 3864488 ns/iter (± 21378) 1.03
es/lexer/colors 15762 ns/iter (± 95) 14958 ns/iter (± 160) 1.05
es/lexer/angular 7701024 ns/iter (± 5151) 7204283 ns/iter (± 57825) 1.07
es/lexer/backbone 985201 ns/iter (± 582) 962677 ns/iter (± 6907) 1.02
es/lexer/jquery 5566996 ns/iter (± 5157) 5532024 ns/iter (± 10802) 1.01
es/lexer/jquery mobile 8591929 ns/iter (± 7676) 8515450 ns/iter (± 32218) 1.01
es/lexer/mootools 4415109 ns/iter (± 4062) 4371988 ns/iter (± 21527) 1.01
es/lexer/underscore 830664 ns/iter (± 3280) 827526 ns/iter (± 5228) 1.00
es/lexer/three 26169446 ns/iter (± 50125) 26094930 ns/iter (± 39349) 1.00
es/lexer/yui 4716670 ns/iter (± 1314) 4653500 ns/iter (± 40661) 1.01
es/parser/colors 29226 ns/iter (± 45) 29909 ns/iter (± 213) 0.98
es/parser/angular 15197536 ns/iter (± 65913) 15329675 ns/iter (± 111139) 0.99
es/parser/backbone 2227067 ns/iter (± 14642) 2230130 ns/iter (± 15381) 1.00
es/parser/jquery 12191045 ns/iter (± 149359) 12167794 ns/iter (± 148246) 1.00
es/parser/jquery mobile 19055793 ns/iter (± 317294) 18793347 ns/iter (± 127951) 1.01
es/parser/mootools 9317262 ns/iter (± 52939) 9251594 ns/iter (± 62386) 1.01
es/parser/underscore 1893464 ns/iter (± 11425) 1897340 ns/iter (± 27860) 1.00
es/parser/three 56148687 ns/iter (± 710292) 53733442 ns/iter (± 998298) 1.04
es/parser/yui 9211460 ns/iter (± 39202) 9312505 ns/iter (± 61649) 0.99
es/preset-env/usage/builtin_type 136424 ns/iter (± 31100) 143319 ns/iter (± 34393) 0.95
es/preset-env/usage/property 20739 ns/iter (± 83) 21297 ns/iter (± 89) 0.97
es/resolver/typescript 114080514 ns/iter (± 1801272) 112709102 ns/iter (± 2124692) 1.01
es/fixer/typescript 79227345 ns/iter (± 1865033) 75937954 ns/iter (± 1266193) 1.04
es/hygiene/typescript 170376990 ns/iter (± 2609513) 161456485 ns/iter (± 1616487) 1.06
es/resolver_with_hygiene/typescript 312100709 ns/iter (± 4603157) 303116370 ns/iter (± 3519440) 1.03
es/visitor/base-perf/module_clone 78276 ns/iter (± 1260) 80482 ns/iter (± 1580) 0.97
es/visitor/base-perf/fold_empty 88599 ns/iter (± 1085) 89906 ns/iter (± 1165) 0.99
es/visitor/base-perf/fold_noop_impl_all 90654 ns/iter (± 2003) 90372 ns/iter (± 1557) 1.00
es/visitor/base-perf/fold_noop_impl_vec 91163 ns/iter (± 1199) 90005 ns/iter (± 1321) 1.01
es/visitor/base-perf/boxing_boxed_clone 57 ns/iter (± 0) 57 ns/iter (± 0) 1
es/visitor/base-perf/boxing_unboxed_clone 54 ns/iter (± 0) 54 ns/iter (± 0) 1
es/visitor/base-perf/boxing_boxed 105 ns/iter (± 0) 103 ns/iter (± 0) 1.02
es/visitor/base-perf/boxing_unboxed 97 ns/iter (± 0) 97 ns/iter (± 0) 1
es/visitor/base-perf/visit_contains_this 3228 ns/iter (± 92) 3211 ns/iter (± 101) 1.01
es/base/parallel/resolver/typescript 5985670033 ns/iter (± 393151667) 5996723366 ns/iter (± 323289861) 1.00
es/base/parallel/hygiene/typescript 1973179844 ns/iter (± 21293667) 1955402935 ns/iter (± 24068907) 1.01
misc/visitors/time-complexity/time 5 93 ns/iter (± 0) 98 ns/iter (± 0) 0.95
misc/visitors/time-complexity/time 10 313 ns/iter (± 0) 335 ns/iter (± 3) 0.93
misc/visitors/time-complexity/time 15 604 ns/iter (± 7) 671 ns/iter (± 14) 0.90
misc/visitors/time-complexity/time 20 1173 ns/iter (± 15) 1239 ns/iter (± 11) 0.95
misc/visitors/time-complexity/time 40 6007 ns/iter (± 68) 6393 ns/iter (± 19) 0.94
misc/visitors/time-complexity/time 60 15256 ns/iter (± 66) 14187 ns/iter (± 59) 1.08
es/full-target/es2016 249782 ns/iter (± 352) 243908 ns/iter (± 1523) 1.02
es/full-target/es2017 242273 ns/iter (± 485) 240228 ns/iter (± 1099) 1.01
es/full-target/es2018 232111 ns/iter (± 376) 230531 ns/iter (± 1573) 1.01
es2020_nullish_coalescing 90936 ns/iter (± 282) 88908 ns/iter (± 968) 1.02
es2020_optional_chaining 124103 ns/iter (± 297) 120920 ns/iter (± 1264) 1.03
es2022_class_properties 147266 ns/iter (± 168) 141468 ns/iter (± 1776) 1.04
es2018_object_rest_spread 94636 ns/iter (± 217) 90677 ns/iter (± 661) 1.04
es2019_optional_catch_binding 83773 ns/iter (± 270) 81302 ns/iter (± 1000) 1.03
es2017_async_to_generator 84264 ns/iter (± 730) 82523 ns/iter (± 1212) 1.02
es2016_exponentiation 88976 ns/iter (± 283) 84931 ns/iter (± 532) 1.05
es2015_arrow 92828 ns/iter (± 309) 89959 ns/iter (± 952) 1.03
es2015_block_scoped_fn 90701 ns/iter (± 232) 87126 ns/iter (± 575) 1.04
es2015_block_scoping 168673 ns/iter (± 219) 161717 ns/iter (± 1849) 1.04

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

Please sign in to comment.