mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-06 17:34:25 +00:00
perf(transformer): pre-size statement vecs in TS enum & namespace lowering (#23516)
## What Two zero-capacity arena `Vec`s in the TypeScript transformer were filled in known-length loops and grew via reallocation. Pre-size them — mirroring the JSX-props pre-size in #23466: - **`transform_ts_enum_members`**: emits exactly `members.len() + 1` statements (one per member + the final `return`) → `vec_with_capacity(members.len() + 1)` (an **exact** capacity). - **TS namespace `enter_program`**: rebuilds the program body; pre-size to `program.body.len()` (an estimate — most statements pass through 1:1). ## Δ — fewer reallocations on TS fixtures `allocs_transformer.snap`, reallocation count: | fixture | before | after | | --- | --- | --- | | checker.ts | 64 | **5** | | kitchen-sink.tsx | 304 | **280** | | App.tsx | 25 | **17** | | binder.ts | 6 | **0** | (allocation **count** and **bytes** are unchanged — this removes the intermediate growth reallocations.) ## Why it is behavior-preserving Capacity-only: `vec_with_capacity` differs from `vec` solely in initial capacity; element type, push order, and contents are identical, so the produced AST is byte-identical. `oxc_transformer` tests pass. Prepared with AI assistance.
This commit is contained in:
1 parent
84438bebab
commit
dfb52b628a
3 files changed
+11
-7
No files matched your search
@@ -310,7 +310,9 @@ impl<'a> TypeScriptEnum {
|
||||
) -> ArenaVec<'a, Statement<'a>> {
|
||||
let ast = ctx.ast;
|
||||
|
||||
let mut statements = ast.vec();
|
||||
// Each member pushes exactly one statement, plus a final `return` statement,
|
||||
// so the length is known up front — pre-size to avoid growth reallocations.
|
||||
let mut statements = ast.vec_with_capacity(members.len() + 1);
|
||||
|
||||
// If enum number has no initializer, its value will be the previous member value + 1,
|
||||
// if it's the first member, it will be `0`.
|
||||
|
||||
@@ -37,8 +37,10 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptNamespace {
|
||||
|
||||
// Recreate the statements vec for memory efficiency.
|
||||
// Inserting the `let` declaration multiple times will reallocate the whole statements vec
|
||||
// every time a namespace declaration is encountered.
|
||||
let mut new_stmts = ctx.ast.vec();
|
||||
// every time a namespace declaration is encountered. Pre-size to the current body length
|
||||
// (a lower bound — namespaces expand) to avoid the growth reallocations for the common
|
||||
// pass-through statements.
|
||||
let mut new_stmts = ctx.ast.vec_with_capacity(program.body.len());
|
||||
|
||||
for stmt in program.body.take_in(ctx.ast) {
|
||||
match stmt {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
File | File size || Sys allocs | Sys reallocs || Arena allocs | Arena reallocs
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
checker.ts | 2.92 MB || 20 | 0 || 4400 | 64
|
||||
checker.ts | 2.92 MB || 20 | 0 || 4400 | 5
|
||||
|
||||
App.tsx | 415.34 kB || 25 | 2 || 719 | 25
|
||||
App.tsx | 415.34 kB || 25 | 2 || 719 | 17
|
||||
|
||||
RadixUIAdoptionSection.jsx | 2.52 kB || 21 | 2 || 259 | 13
|
||||
|
||||
@@ -10,7 +10,7 @@ pdf.mjs | 567.30 kB || 15 | 0 |
|
||||
|
||||
antd.js | 6.69 MB || 15 | 0 || 2 | 0
|
||||
|
||||
binder.ts | 193.08 kB || 17 | 0 || 379 | 6
|
||||
binder.ts | 193.08 kB || 17 | 0 || 379 | 0
|
||||
|
||||
kitchen-sink.tsx | 732.90 kB || 184 | 3 || 6690 | 304
|
||||
kitchen-sink.tsx | 732.90 kB || 184 | 3 || 6690 | 280
|
||||
|
||||
Reference in new issue
Block a user