-
-
Notifications
You must be signed in to change notification settings - Fork 470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce AST enum type sizes #3047
Comments
Can you try |
Thanks for coming back. Could we start with one of the JSX types first where the savings are likely greater e.g. |
Sounds like a plan. More frequent usages to less. |
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.
Box all enum variants for JSX types (`JSXAttributeName`, `JSXAttributeValue`, `JSXChild`, `JSXElementName`, `JSXMemberExpressionObject`). Part of #3047. I'm not sure how to interpret the benchmark results. As I said on #3047: > I imagine it may cost a little in performance in the parser due to extra calls to `alloc`, but in return traversing the AST should be cheaper, as the data is more compact, so less cache misses. Sure enough, there is a small impact (1%) on the 2 parser benchmarks for JSX files. However, the other benchmarks have too much noise in them to see whether this is repaid in a speed up on transformer etc, especially as the transformer benchmarks also include parsing. What do you think @Boshen?
Similar to #3058 and #3061 it is a continuation of #3047. Handles these enum types: > TSEnumMemberName > Variant sizes: 16, 24, 24, 40 > Unboxed variants: IdentifierName (struct), StringLiteral (struct), NumericLiteral (struct) > Dependents: TSEnumMember (struct) > => Box all variants. > > TSModuleReference > Variant sizes: 16, 32 > Unboxed variants: TSExternalModuleReference (struct) > Dependents: Box<TSModuleReference> in TSImportEqualsDeclaration > => Box all variants. Replace Box<TSModuleReference> with TSModuleReference in TSImportEqualsDeclaration. > > TSTypePredicateName > Variant sizes: 8, 24 > Unboxed variants: IdentifierName (struct), TSThisType (struct) > Dependents: TSTypePredicate (struct) > => Box Identifier variant. Do not box This variant as only 8 bytes (just contains Span). > > TSTypeQueryExprName > Variant sizes: 16, 88 > Unboxed variants: TSImportType (struct) > Dependents: TSTypeQuery (struct) > => Box TSImportType variant. Do not box TSTypeName variant, as is another enum.
All done? |
Yes. Thanks for merging all the PRs. |
In general, Oxc's AST types which are enums have all their variants boxed. e.g.:
The enum then only weighs 16 bytes, and is used unboxed in other types' fields:
There are however some exceptions to this rule, where enums are larger than they need to be because not all variants are boxed, and some variants are larger than others. This results in less compact storage in the arena, due to excess padding.
Boxing the variants in these cases should save on memory. I imagine it may cost a little in performance in the parser due to extra calls to
alloc
, but in return traversing the AST should be cheaper, as the data is more compact, so less cache misses.However, I am not 100% sure of that in all cases. What I think should be done for each type is listed below, but we should apply each change individually, and check benchmarks to ensure performance does not degrade.
The affected types are:
ImportDeclarationSpecifier
Variant sizes: 40, 40, 80
Unboxed variants:
ImportSpecifier
(struct),ImportDefaultSpecifier
(struct),ImportNamespaceSpecifier
(struct)Dependents:
Vec<ImportDeclarationSpecifier>
inImportDeclaration
(struct)=> Box all variants.
MemberExpression
Variant sizes: 48, 56, 56
Unboxed variants:
ComputedMemberExpression
(struct),StaticMemberExpression
(struct),PrivateFieldExpression
(struct)Dependents:
Box<MemberExpression>
inExpression
(enum),SimpleAssignmentTarget
(enum),ChainElement
(enum)=> Not sure. Always used within box as another enum variant. Would be better to box variants and flatten this enum into parent enums, but that's tricky.
ModuleExportName
Variant sizes: 24, 24
Unboxed variants:
IdentifierName
(struct),StringLiteral
(struct)Dependents:
ImportSpecifier
(struct)Option<ModuleExportName>
inExportAllDeclaration
(struct)ExportDefaultDeclaration
(struct)ExportSpecifier
(struct)=> Not sure. Would be good if
ExportAllDeclaration::exported
could be reduced in size (it's currentlyOption<ModuleExportName>
) but otherwise, fine to leave as is.JSXAttributeName
Variant sizes: 8, 24
Unboxed variants:
JSXIdentifier
(struct)Dependents:
JSXAttribute
(struct)=> Probably box all variants.
JSXAttributeValue
Variant sizes: 8, 8, 24, 32
Unboxed variants:
StringLiteral
(struct),JSXExpressionContainer
(struct)Dependents:
Option<JSXAttributeValue>
inJSXAttribute
= Probably box all variants.
JSXChild
Variant sizes: 8, 8, 24, 24, 32
Unboxed variants:
JSXText
(struct),JSXExpressionContainer
(struct),JSXSpreadChild
(struct)Dependents:
Vec<JSXChild>
inJSXElement
(struct) andJSXFragment
(struct)=> Box all variants.
JSXElementName
Variant sizes: 8, 8, 24
Unboxed variants:
JSXIdentifier
(struct)Dependents:
JSXOpeningElement
(struct),JSXClosingElement
(struct)=> Probably box all variants.
JSXMemberExpressionObject
Variant sizes: 8, 24
Unboxed variants:
JSXIdentifier
(struct)Dependents:
JSXMemberExpression
(struct)=> Probably box all variants.
TSEnumMemberName
Variant sizes: 16, 24, 24, 40
Unboxed variants:
IdentifierName
(struct),StringLiteral
(struct),NumericLiteral
(struct)Dependents:
TSEnumMember
(struct)=> Box all variants.
TSModuleReference
Variant sizes: 16, 32
Unboxed variants:
TSExternalModuleReference
(struct)Dependents:
Box<TSModuleReference>
inTSImportEqualsDeclaration
=> Box all variants. Replace
Box<TSModuleReference>
withTSModuleReference
inTSImportEqualsDeclaration
.TSTypePredicateName
Variant sizes: 8, 24
Unboxed variants:
IdentifierName
(struct),TSThisType
(struct)Dependents:
TSTypePredicate
(struct)=> Box
Identifier
variant. Do not boxThis
variant as only 8 bytes (just containsSpan
).TSTypeQueryExprName
Variant sizes: 16, 88
Unboxed variants:
TSImportType
(struct)Dependents:
TSTypeQuery
(struct)=> Box
TSImportType
variant. Do not boxTSTypeName
variant, as is another enum.The text was updated successfully, but these errors were encountered: