-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Possible optimizations to Semantic
. I'll add to this list as I learn more about how it works:
- Optimize structs-of-arrays (Optimize
Semantic
's structs-of-arrays and make API simpler #11, UseIndexVec
notFxHashMap
for all fields ofScopeTree
oxc#4269) - Store Semantic data in arena (Store
Semantic
data in arena #31) - Re-design
ScopeFlags
(Re-designScopeFlags
#16) unresolved_references
doesn't need to be stored inScopeTree
, only a singleVec
forroot_unresolved_references
.unresolved_references
is used internally withinSemantic
while resolving references, but at the end, it's an emptyVec
for every scope except root scope. Store it inSemanticBuilder
instead and discard at the end. perf(semantic): keep a single map of unresolved references oxc#4107unresolved_references
does not need to retain entries for every scope. Could be a stack where we reuse hash maps from previous scopes (see perf(semantic): keep a single map of unresolved references oxc#4107 (comment)).unresolved_references
could be a linked list / chunked linked list instead of aVec
. I don't think it's ever indexed into.- Reduce hashing when resolving references. If current
unresolved_references
hash map contains hashes already, no need to hash each identifier again when finding entry in parent hash map (maybe hash map doesn't contain hashes - SwissTable-style hash maps don't, I think - in which case we could store hashes in entries). - Store binding names as
Atom<'a>
notCompactStr
. Conversion toCompactStr
causes unnecessary allocations. We can just reference strings in source text (asAtom
does). Reference::name
field is unnecessary for bound references - can be got fromSymbolId
. Is needed for unbound references, but they could be stored elsewhere and referenced.- Add a scope for "global" which would contain unbound references (replacing root
unresolved_references
)? Then every reference has aSymbolId
. - Initialize
Semantic
'sVec
s with sufficient capacity so they don't need to grow (see StoreSemantic
data in arena #31). - Get rid of
Reference
.- Store
SymbolId
instead ofReferenceId
inIdentifierReference
. - Store a reference count for each symbol so you can check if a symbol is referenced or not.
- Need some way in semantic to update
SymbolId
forIdentifierReference
s long after exiting the node. Would need a pointer-based solution, orCell<SymbolId>
. - Only thing we lose is the
AstNodeId
inReference
. This is probably used in linter, but I don't know what for, and how easy to replace it. - This would allow removing the
resolved_references: IndexVec<SymbolId, Vec<ReferenceId>>
field inSymbolTable
which is major source of reallocation in semantic, asVec<ReferenceId>
is pushed to every time aIdentifierReference
is found, and has an inherently unpredictable growth pattern (can't know in advance how big it needs to be).
- Store
- Don't use
Nodes
withinSemanticBuilder
. We can get type of parent node etc by maintaining stacks in the visitor. This will enable us to have a cut-down version ofSemanticBuilder
which doesn't buildNodes
.
Metadata
Metadata
Assignees
Labels
No labels