Skip to content

Optimize unresolved references in semantic #4169

@overlookmotel

Description

@overlookmotel

#4162 boosted perf of semantic by turning unresolved_references into a stack.

I think we can potentially do even better. From #4162 (comment):

What I had in mind is that you never call unresolved_references.pop(). Instead, hold on to the hash map and re-use it. That way we avoid generating (and allocating) new hash map when entering a scope most of the time.

unresolved_references is Vec<UnresolvedReferences>, indexed by scope depth.

e.g. with this input:

function foo() {}
function bar() {}
  • Enter top level scope:
    • Depth is 0.
    • Push a UnresolvedReferences hash map to unresolved_references.
    • Current hashmap is unresolved_references[0].
  • Enter scope for foo:
    • Increment depth to 1.
    • Push another UnresolvedReferences hash map to unresolved_references.
    • Current hashmap is unresolved_references[1].
  • Exit scope for foo:
    • Clear current hashmap (unresolved_references[1]).
    • Decrement depth to 0.
    • Do NOT pop from unresolved_references.
    • Current hashmap is now unresolved_references[0].
  • Enter scope for bar:
    • Increment depth to 1.
    • Do NOT push to unresolved_references.
    • Current hashmap is unresolved_references[1] (i.e. reuse same hash map that was used for foo)
  • Exit scope for bar: same as for foo
  • Exit top level scope: same

I think this would be a further perf boost due to reducing allocations, and reusing allocations which are already warm in the cache.

cc @lucab (though no obligation on you to do this)

Metadata

Metadata

Assignees

Labels

A-semanticArea - SemanticC-performanceCategory - Solution not expected to change functional behavior, only performance

Type

No type

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions