Skip to content

perf(semantic): share one clone_in across symbol creation and binding insertion#22666

Closed
Dunqing wants to merge 1 commit into
mainfrom
claude/perf-semantic-add-root-unresolved
Closed

perf(semantic): share one clone_in across symbol creation and binding insertion#22666
Dunqing wants to merge 1 commit into
mainfrom
claude/perf-semantic-add-root-unresolved

Conversation

@Dunqing

@Dunqing Dunqing commented May 22, 2026

Copy link
Copy Markdown
Member

Summary

declare_symbol_on_scope and declare_shadow_symbol both called create_symbol(name, …) followed by add_binding / insert_binding on the same name. Each function did its own name.clone_in(allocator), copying the same identifier bytes into the scoping arena twice on every new binding.

Add a private helper Scoping::create_symbol_with_binding that performs both inserts inside a single with_dependent_mut call, sharing one cloned Ident<'cell> between the symbol_names vector and the bindings map. The returned SymbolId is computed from symbol_table.len() before push, matching the id symbol_table.push would return — symbol_names is kept in lock-step with symbol_table.

For shadow symbols (e.g. catch parameters) the bind-scope can differ from the symbol's owner scope, so the helper takes both separately.

Scoping::insert_binding is removed — its only caller (declare_shadow_symbol) now goes through the combined helper.

Measurements

cargo bench --bench semantic --no-default-features --features compiler on TestFiles::minimal(), criterion baseline vs. this PR, M3-class machine:

file before after change
RadixUIAdoptionSection.jsx 3.05 µs 2.98 µs −1.68 %
react.development.js 134.33 µs 132.60 µs −1.98 %
cal.com.tsx 2.776 ms 2.690 ms −3.10 %
binder.ts 310.90 µs 303.24 µs −2.73 %
kitchen-sink.tsx 2.628 ms 2.600 ms −1.07 %

All five deltas are statistically significant per criterion (p < 0.05).

Verified by cargo test -p oxc_semantic --features cfg (72 tests), cargo clippy -p oxc_semantic --all-features, downstream cargo test -p oxc_transformer / -p oxc_minifier, and cargo coverage -- semantic (semantic snapshot counts unchanged: 45575/47095 test262, 2035/2236 babel, 2671/4773 typescript, 52/66 misc).

AI assisted.

… insertion

`declare_symbol_on_scope` and `declare_shadow_symbol` both called
`create_symbol(name, ...)` followed by `add_binding` / `insert_binding`
on the same name. Each function did its own `name.clone_in(allocator)`,
copying the same identifier bytes into the scoping arena twice on every
new binding.

Add a private helper `Scoping::create_symbol_with_binding` that performs
both inserts inside a single `with_dependent_mut` call, sharing one
cloned `Ident<'cell>` between the symbol-names vector and the bindings
map. The returned `SymbolId` is computed from `symbol_table.len()`
before `push`, matching the id `push` would return.

For shadow symbols the bind-scope can differ from the symbol's owner
scope (catch parameters), so the helper takes both separately.

Benchmark (`cargo bench --bench semantic`):

- RadixUIAdoptionSection.jsx: -1.68%
- react.development.js:       -1.98%
- cal.com.tsx:                -3.10%
- binder.ts:                  -2.73%
- kitchen-sink.tsx:           -1.07%

Removes the now-unused `Scoping::insert_binding`.
@github-actions github-actions Bot added the A-semantic Area - Semantic label May 22, 2026
@codspeed-hq

codspeed-hq Bot commented May 22, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 57 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing claude/perf-semantic-add-root-unresolved (adf2edb) with main (868e2e8)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Dunqing

Dunqing commented May 22, 2026

Copy link
Copy Markdown
Member Author

Duplicate of #22663

@Dunqing Dunqing marked this as a duplicate of #22663 May 22, 2026
@Dunqing Dunqing closed this May 22, 2026
@Boshen Boshen deleted the claude/perf-semantic-add-root-unresolved branch May 31, 2026 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-semantic Area - Semantic

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant