perf(transformer): use ReplaceWith instead of TakeIn#24015
Conversation
Merging this PR will improve performance by 3.45%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Simulation | codegen[RadixUIAdoptionSection.jsx] |
124.8 µs | 120.6 µs | +3.45% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing om/07-01-perf_transformer_use_replacewith_instead_of_takein_ (0f9d621) with om/07-01-feat_ast_implement_replacewith_on_all_ast_types (4c8d572)2
Footnotes
-
19 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. ↩
-
No successful run was found on
om/07-01-feat_ast_implement_replacewith_on_all_ast_types(8b03eea) during the generation of this report, so a0151ad was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
There was a problem hiding this comment.
Pull request overview
Refactors the Rust transformer to prefer ReplaceWith over TakeIn in mutation patterns where the original node is immediately overwritten, reducing arena allocations (notably for TS-heavy inputs) while keeping transformation semantics the same.
Changes:
- Converted many AST rewrite sites to use
replace_with(...)closures instead oftake_in(...)+ re-assignment. - Simplified a few transformation helpers to avoid requiring an allocator solely for
take_in. - Updated allocation tracking snapshot to reflect reduced arena allocations.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tasks/track_memory_allocations/allocs_transformer.snap | Updates allocation snapshot numbers after reducing arena allocations. |
| crates/oxc_transformer/src/typescript/namespace.rs | Uses ReplaceWith for initializer rewrites in namespace handling. |
| crates/oxc_transformer/src/typescript/class.rs | Rewrites computed key sequencing using replace_with. |
| crates/oxc_transformer/src/typescript/annotations.rs | Unwraps TS-syntax expressions / consequent rewriting via replace_with. |
| crates/oxc_transformer/src/plugins/tagged_template_transform.rs | Rewrites tagged template transform to use replace_with. |
| crates/oxc_transformer/src/plugins/styled_components.rs | Refactors withConfig call rewrite to use replace_with. |
| crates/oxc_transformer/src/lib.rs | Refactors “wrap last expression statement in return” logic to use replace_with. |
| crates/oxc_transformer/src/jsx/refresh.rs | Uses replace_with for call/assignment wrapping to avoid dummy nodes. |
| crates/oxc_transformer/src/jsx/jsx_impl.rs | Switches JSX expression replacement to replace_with. |
| crates/oxc_transformer/src/es2026/explicit_resource_management.rs | Replaces several statement/body rewrites with replace_with, including program-body restructuring. |
| crates/oxc_transformer/src/es2022/class_properties/super_converter.rs | Refactors super assignment/update expression rewrites to replace_with. |
| crates/oxc_transformer/src/es2022/class_properties/private_field.rs | Uses replace_with in multiple private-field transforms to reduce arena churn. |
| crates/oxc_transformer/src/es2022/class_properties/constructor.rs | Refactors super call replacement to replace_with. |
| crates/oxc_transformer/src/es2020/optional_chaining.rs | Uses replace_with for object/callee sequencing and eval?.() rewrite. |
| crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs | Refactors ?? logical-expression transform to use replace_with. |
| crates/oxc_transformer/src/es2018/object_rest_spread.rs | Refactors sequence/block wrapping to use replace_with. |
| crates/oxc_transformer/src/es2017/async_to_generator.rs | Uses replace_with for arrow-body “expression → return” conversion. |
| crates/oxc_transformer/src/es2016/exponentiation_operator.rs | Refactors pow conversions and sequencing to use replace_with. |
| crates/oxc_transformer/src/decorator/legacy/mod.rs | Uses replace_with for computed key capture assignment. |
| crates/oxc_transformer/src/common/arrow_function_converter.rs | Refactors arrow-function conversion and super-call sequencing to use replace_with. |
| crates/oxc_transformer_plugins/src/replace_global_defines.rs | Uses replace_with to unwrap ChainExpression without allocator-dependent take_in. |
| crates/oxc_transformer_plugins/src/module_runner_transform.rs | Refactors dynamic import transform to use replace_with. |
24991e8 to
c6bc59b
Compare
d61e3e8 to
547d76d
Compare
c6bc59b to
4c8d572
Compare
547d76d to
9d36ab6
Compare
4c8d572 to
8b03eea
Compare
9d36ab6 to
0f9d621
Compare
Merge activity
|
Replace `take_in` with `replace_with` in as many places as possible in transformer. See #24012 for explanation of the advantage of `replace_with`. This has only a minimal perf effect according to Codspeed benchmarks (1% improvement). But it does cut the number of arena allocations on TS files by 50%, so reduces memory usage.
8b03eea to
61fbf10
Compare
0f9d621 to
ff10855
Compare
### 🚀 Features - 260425f semantic/examples: Include unresolved references (#24214) (camc314) - 2d9b0b3 minifier: Fold boolean-literal ternary branches in value contexts (#24110) (Dunqing) - 61fbf10 ast: Implement `ReplaceWith` on all AST types (#24013) (overlookmotel) - 7db7a29 allocator: Add `ReplaceWith` trait (#24012) (overlookmotel) - 4eb074e mangler: Add `reserved` option for names that must not be mangled (#24041) (Dunqing) - 2e62012 data_structures: Add `StringExt` trait (#24006) (overlookmotel) - 60e7160 minifier: Drop side-effect-free IIFEs whose result is unused (#23967) (Dunqing) - 26dd9e2 ast: Add method to widen inherited enum ref to parent ref (#23961) (overlookmotel) ### 🐛 Bug Fixes - e8b50ee transformer: Clean up semantics for stripped TypeScript syntax (#24180) (camc314) - d966d0b react_compiler: Remove clippy allows (#24168) (Boshen) - 854ef8d react_compiler: Compile generic functions instead of over-bailing on type-param hoisting (#24158) (Boshen) - 093586c react_compiler: Align memoization cache-slot allocation with Babel (#24157) (Boshen) - 09c8f59 react_compiler: Normalize snapshot fixture paths (#24142) (camc314) - f13df97 react_compiler: Drop stray empty statement from catch bindings (#24133) (Boshen) - cb2a505 react_compiler: Codegen destructuring reassignment targets (#24131) (Boshen) - b82c394 react_compiler: Propagate codegen invariants instead of emitting empty bodies (#24128) (Boshen) - 5771982 react_compiler: Render unchanged programs as source in fixture snapshots (#24129) (Boshen) - 4b16e1a transformer/async-to-generator: Preserve direct eval scope flags (#24136) (camc314) - 4e9194f react_compiler: Lower `delete obj.prop` to Property/ComputedDelete (#24123) (Boshen) - 0b25582 ast: Type binding node `typeAnnotation` as `TSTypeAnnotation | null` (#23113) (Boshen) - 018c0e5 transformer: Hoist lowered async declarations (#22770) (camc314) - 652fbaf mangler: Keep names of destructured exported bindings (#24036) (Dunqing) - e274415 minifier: Don't drop global calls that throw despite pure arguments (#23917) (Dunqing) - 59abb30 minifier: Only merge string literals in `try_fold_add` when the inner operator is `+` (#23622) (Jerry Zhao) ### ⚡ Performance - c5ca77b transformer: Avoid cloning refresh options (#24191) (camc314) - bf1a151 react_compiler: Compile out debug printers (#24184) (Boshen) - abb44a0 transformer: Build fixed object-rest arguments (#24190) (camc314) - a4db731 isolated_declarations: Use `ReplaceWith` instead of `TakeIn` (#24016) (overlookmotel) - ff10855 transformer: Use `ReplaceWith` instead of `TakeIn` (#24015) (overlookmotel) - bd49aff ecmascript: Avoid heap-allocating Math.min/max/imul operands (#23941) (Lawrence Lin) - e4b708b react_compiler: Skip compiled files before prefilters (#24171) (Boshen) - c59f2fe rust: Return impl ExactSizeIterator from slice-backed accessors (#24144) (Boshen) - 5d6d04a codegen: SWAR-skip boring byte runs in sourcemap line/column scan (#24023) (Boshen) - a55e0be traverse: Reduce string operations in `get_var_name_from_node` (#24007) (overlookmotel) - e6d48e1 transformer/nullish_coalescing: Move cold path into separate function (#23989) (overlookmotel) - c4e35b5 transformer/object_rest_spread: Pre-allocate capacity in `Vec` (#23988) (overlookmotel) - 527b8e5 transformer/decorators: Narrow type earlier (#23987) (overlookmotel) ### 📚 Documentation - 30d17f5 allocator: Clarify docs for `TakeIn::take_in_box` (#24093) (overlookmotel) - 675e6a8 ast: Correct doc comment for `PrivateFieldExpression` (#24008) (overlookmotel) - e4c30e6 minifier: Explain what `dce` mode means (#23994) (Dunqing) - 37cbf88 ast_macros: Document fields of `StructDetails` (#23959) (overlookmotel) - 4de3e54 ast: Correct doc comment (#23948) (overlookmotel) Co-authored-by: Boshen <[email protected]>

Replace
take_inwithreplace_within as many places as possible in transformer. See #24012 for explanation of the advantage ofreplace_with.This has only a minimal perf effect according to Codspeed benchmarks (1% improvement). But it does cut the number of arena allocations on TS files by 50%, so reduces memory usage.