perf(ast): box ImportDeclarationSpecifier enum variants (#3061)

Part of #3047.

As with #3058, it's hard to interpret the benchmark results here. But in
this case I think it's easier to see from "first principles" that this
should be an improvement - `ImportSpecifier` is pretty massive (80
bytes) vs `ImportDefaultSpecifier` (40 bytes), and the latter (e.g.
`import React from 'react'`) is common in JS code.
This commit is contained in:
overlookmotel 2024-04-22 02:06:39 +01:00 committed by GitHub
parent 2804e7dbf6
commit 383b449d4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 18 additions and 15 deletions

View file

@ -2373,11 +2373,11 @@ pub struct ImportDeclaration<'a> {
pub enum ImportDeclarationSpecifier<'a> {
/// import {imported} from "source"
/// import {imported as local} from "source"
ImportSpecifier(ImportSpecifier<'a>),
ImportSpecifier(Box<'a, ImportSpecifier<'a>>),
/// import local from "source"
ImportDefaultSpecifier(ImportDefaultSpecifier<'a>),
ImportDefaultSpecifier(Box<'a, ImportDefaultSpecifier<'a>>),
/// import * as local from "source"
ImportNamespaceSpecifier(ImportNamespaceSpecifier<'a>),
ImportNamespaceSpecifier(Box<'a, ImportNamespaceSpecifier<'a>>),
}
// import {imported} from "source"

View file

@ -107,10 +107,9 @@ impl<'a> ParserImpl<'a> {
fn parse_import_default_specifier(&mut self) -> Result<ImportDeclarationSpecifier<'a>> {
let span = self.start_span();
let local = self.parse_binding_identifier()?;
Ok(ImportDeclarationSpecifier::ImportDefaultSpecifier(ImportDefaultSpecifier {
span: self.end_span(span),
local,
}))
Ok(ImportDeclarationSpecifier::ImportDefaultSpecifier(
self.ast.alloc(ImportDefaultSpecifier { span: self.end_span(span), local }),
))
}
// import * as name from "module-name"
@ -119,10 +118,9 @@ impl<'a> ParserImpl<'a> {
self.bump_any(); // advance `*`
self.expect(Kind::As)?;
let local = self.parse_binding_identifier()?;
Ok(ImportDeclarationSpecifier::ImportNamespaceSpecifier(ImportNamespaceSpecifier {
span: self.end_span(span),
local,
}))
Ok(ImportDeclarationSpecifier::ImportNamespaceSpecifier(
self.ast.alloc(ImportNamespaceSpecifier { span: self.end_span(span), local }),
))
}
// import { export1 , export2 as alias2 , [...] } from "module-name";
@ -384,7 +382,7 @@ impl<'a> ParserImpl<'a> {
// ImportSpecifier :
// ImportedBinding
// ModuleExportName as ImportedBinding
pub(crate) fn parse_import_specifier(&mut self) -> Result<ImportSpecifier<'a>> {
pub(crate) fn parse_import_specifier(&mut self) -> Result<Box<'a, ImportSpecifier<'a>>> {
let specifier_span = self.start_span();
let peek_kind = self.peek_kind();
let mut import_kind = ImportOrExportKind::Value;
@ -415,7 +413,12 @@ impl<'a> ParserImpl<'a> {
let imported = IdentifierName { span: local.span, name: local.name.clone() };
(ModuleExportName::Identifier(imported), local)
};
Ok(ImportSpecifier { span: self.end_span(specifier_span), imported, local, import_kind })
Ok(self.ast.alloc(ImportSpecifier {
span: self.end_span(specifier_span),
imported,
local,
import_kind,
}))
}
// ModuleExportName :

View file

@ -85,7 +85,7 @@ impl<'a> ModuleImports<'a> {
names: std::vec::Vec<NamedImport>,
) -> Statement<'a> {
let specifiers = self.ast.new_vec_from_iter(names.into_iter().map(|name| {
ImportDeclarationSpecifier::ImportSpecifier(ImportSpecifier {
ImportDeclarationSpecifier::ImportSpecifier(self.ast.alloc(ImportSpecifier {
span: SPAN,
imported: ModuleExportName::Identifier(IdentifierName::new(
SPAN,
@ -96,7 +96,7 @@ impl<'a> ModuleImports<'a> {
self.ast.new_atom(name.local.unwrap_or(name.imported).as_str()),
),
import_kind: ImportOrExportKind::Value,
})
}))
}));
let import_stmt = self.ast.import_declaration(
SPAN,