-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce amount of code generated by ValueDebugFormat #8239
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The latest updates on your projects. Learn more about Vercel for Git ↗︎
8 Ignored Deployments
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
🟢 Turbopack Benchmark CI successful 🟢Thanks |
✅ This change can build |
kdy1
approved these changes
May 29, 2024
While the code generated for unit structs would *technically* work, it accidentally created a variable binding the value to the struct name. That struct name is naturally CamelCase, which would then create compiler warnings inside the macro about `snake_case`. I don't think this was directly caused by my PR, but empty structs are now treated as unit structs, and unit structs were broken, so this surfaced the issue.
bgw
force-pushed
the
bgw/smaller-value-debug-format
branch
from
June 4, 2024 21:01
649143c
to
4c1ca5a
Compare
kdy1
added a commit
to vercel/next.js
that referenced
this pull request
Jun 5, 2024
# Turbopack * vercel/turborepo#8272 <!-- Donny/강동윤 - feat: Update `swc_core` to `v0.92.8` --> * vercel/turborepo#8262 <!-- Alexander Lyon - add crate to calculate prehashes --> * vercel/turborepo#8174 <!-- Tobias Koppers - use prehash to avoid rehashing the key in the task cache --> * vercel/turborepo#7674 <!-- Alexander Lyon - [turbo trace] add ability to filter by value and occurences --> * vercel/turborepo#8287 <!-- Donny/강동윤 - feat: Update `swc_core` to `v0.92.10` --> * vercel/turborepo#8037 <!-- Alexander Lyon - create turbo-static for compile time graph analysis --> * vercel/turborepo#8293 <!-- Will Binns-Smith - Sync Cargo.lock with Next.js --> * vercel/turborepo#8239 <!-- Benjamin Woodruff - Reduce amount of code generated by ValueDebugFormat --> * vercel/turborepo#8304 <!-- Benjamin Woodruff - Minor optimizations to the codegen of TaskFnInputFunction --> * vercel/turborepo#8221 <!-- Donny/강동윤 - perf: Introduce `RcStr` --> ### What? I tried using `Arc<String>` in vercel/turborepo#7772, but a team member suggested creating a new type so we can replace underlying implementation easily in the future. ### Why? To reduce memory usage. ### How? Closes PACK-2776
ForsakenHarmony
pushed a commit
to vercel/next.js
that referenced
this pull request
Jul 25, 2024
…#8239) I noticed that `ValueDebugFormat` was pretty common near the top of `cargo llvm-lines`. It looked like this was probably due to the large number of await points inserted into the code. Each await point complicates the state machine that rustc must generate and pass to LLVM. This reduces the number of await points from one per field to one per struct. There's a minor change in behavior as the child fields are awaited concurrently (`join_all`) instead of one-at-a-time. ## Why? Less code generated by macros and passed to LLVM should mean faster compiles and a smaller binary that we're shipping to the user. The total change here is pretty small though, so it's probably not worth benchmarking compile times. ## Testing ``` cargo test -p turbo-tasks-macros-tests ``` ## cargo llvm-lines (sanity check) ``` cargo llvm-lines -p next-swc-napi ``` Before: ``` Lines Copies Function name ----- ------ ------------- 1094257 31851 (TOTAL) ... 1246 (0.1%, 2.2%) 1 (0.0%, 0.0%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` After: ``` Lines Copies Function name ----- ------ ------------- 1088974 31851 (TOTAL) ... 462 (0.0%, 7.7%) 1 (0.0%, 0.3%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` ## Binary size (next-swc, stripped arm64 linux tarball) Before: `188180480 bytes` After: `187443200 bytes` <details> <summary><strong>Example Generated Code (After)</strong> </summary> ```rust // ================================================= // Recursive expansion of the ValueDebugFormat macro // ================================================= impl turbo_tasks::debug::ValueDebugFormat for ComponentsForJs { fn value_debug_format<'a>( &'a self, depth: usize, ) -> turbo_tasks::debug::ValueDebugFormatString<'a> { turbo_tasks::debug::ValueDebugFormatString::Async(Box::pin(async move { if depth == 0 { return Ok(stringify!(ComponentsForJs).to_string()); } use turbo_tasks::debug::{internal::*, ValueDebugFormat}; Ok(format!( "{:#?}", match self { ComponentsForJs { page, layout, error, loading, template, not_found, default, route, metadata, } => FormattingStruct::new_named_async( stringify!(ComponentsForJs), vec![ AsyncFormattingField::new( stringify!(page), turbo_tasks::macro_helpers::value_debug_format_field( page.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(layout), turbo_tasks::macro_helpers::value_debug_format_field( layout.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(error), turbo_tasks::macro_helpers::value_debug_format_field( error.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(loading), turbo_tasks::macro_helpers::value_debug_format_field( loading.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(template), turbo_tasks::macro_helpers::value_debug_format_field( template.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(not_found), turbo_tasks::macro_helpers::value_debug_format_field( not_found.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(default), turbo_tasks::macro_helpers::value_debug_format_field( default.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(route), turbo_tasks::macro_helpers::value_debug_format_field( route.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(metadata), turbo_tasks::macro_helpers::value_debug_format_field( metadata.value_debug_format(depth.saturating_sub(1)) ), ), ], ) .await, } )) })) } } ``` </details>
ForsakenHarmony
pushed a commit
to vercel/next.js
that referenced
this pull request
Jul 29, 2024
…#8239) I noticed that `ValueDebugFormat` was pretty common near the top of `cargo llvm-lines`. It looked like this was probably due to the large number of await points inserted into the code. Each await point complicates the state machine that rustc must generate and pass to LLVM. This reduces the number of await points from one per field to one per struct. There's a minor change in behavior as the child fields are awaited concurrently (`join_all`) instead of one-at-a-time. ## Why? Less code generated by macros and passed to LLVM should mean faster compiles and a smaller binary that we're shipping to the user. The total change here is pretty small though, so it's probably not worth benchmarking compile times. ## Testing ``` cargo test -p turbo-tasks-macros-tests ``` ## cargo llvm-lines (sanity check) ``` cargo llvm-lines -p next-swc-napi ``` Before: ``` Lines Copies Function name ----- ------ ------------- 1094257 31851 (TOTAL) ... 1246 (0.1%, 2.2%) 1 (0.0%, 0.0%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` After: ``` Lines Copies Function name ----- ------ ------------- 1088974 31851 (TOTAL) ... 462 (0.0%, 7.7%) 1 (0.0%, 0.3%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` ## Binary size (next-swc, stripped arm64 linux tarball) Before: `188180480 bytes` After: `187443200 bytes` <details> <summary><strong>Example Generated Code (After)</strong> </summary> ```rust // ================================================= // Recursive expansion of the ValueDebugFormat macro // ================================================= impl turbo_tasks::debug::ValueDebugFormat for ComponentsForJs { fn value_debug_format<'a>( &'a self, depth: usize, ) -> turbo_tasks::debug::ValueDebugFormatString<'a> { turbo_tasks::debug::ValueDebugFormatString::Async(Box::pin(async move { if depth == 0 { return Ok(stringify!(ComponentsForJs).to_string()); } use turbo_tasks::debug::{internal::*, ValueDebugFormat}; Ok(format!( "{:#?}", match self { ComponentsForJs { page, layout, error, loading, template, not_found, default, route, metadata, } => FormattingStruct::new_named_async( stringify!(ComponentsForJs), vec![ AsyncFormattingField::new( stringify!(page), turbo_tasks::macro_helpers::value_debug_format_field( page.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(layout), turbo_tasks::macro_helpers::value_debug_format_field( layout.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(error), turbo_tasks::macro_helpers::value_debug_format_field( error.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(loading), turbo_tasks::macro_helpers::value_debug_format_field( loading.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(template), turbo_tasks::macro_helpers::value_debug_format_field( template.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(not_found), turbo_tasks::macro_helpers::value_debug_format_field( not_found.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(default), turbo_tasks::macro_helpers::value_debug_format_field( default.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(route), turbo_tasks::macro_helpers::value_debug_format_field( route.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(metadata), turbo_tasks::macro_helpers::value_debug_format_field( metadata.value_debug_format(depth.saturating_sub(1)) ), ), ], ) .await, } )) })) } } ``` </details>
ForsakenHarmony
pushed a commit
to vercel/next.js
that referenced
this pull request
Jul 29, 2024
…#8239) I noticed that `ValueDebugFormat` was pretty common near the top of `cargo llvm-lines`. It looked like this was probably due to the large number of await points inserted into the code. Each await point complicates the state machine that rustc must generate and pass to LLVM. This reduces the number of await points from one per field to one per struct. There's a minor change in behavior as the child fields are awaited concurrently (`join_all`) instead of one-at-a-time. ## Why? Less code generated by macros and passed to LLVM should mean faster compiles and a smaller binary that we're shipping to the user. The total change here is pretty small though, so it's probably not worth benchmarking compile times. ## Testing ``` cargo test -p turbo-tasks-macros-tests ``` ## cargo llvm-lines (sanity check) ``` cargo llvm-lines -p next-swc-napi ``` Before: ``` Lines Copies Function name ----- ------ ------------- 1094257 31851 (TOTAL) ... 1246 (0.1%, 2.2%) 1 (0.0%, 0.0%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` After: ``` Lines Copies Function name ----- ------ ------------- 1088974 31851 (TOTAL) ... 462 (0.0%, 7.7%) 1 (0.0%, 0.3%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` ## Binary size (next-swc, stripped arm64 linux tarball) Before: `188180480 bytes` After: `187443200 bytes` <details> <summary><strong>Example Generated Code (After)</strong> </summary> ```rust // ================================================= // Recursive expansion of the ValueDebugFormat macro // ================================================= impl turbo_tasks::debug::ValueDebugFormat for ComponentsForJs { fn value_debug_format<'a>( &'a self, depth: usize, ) -> turbo_tasks::debug::ValueDebugFormatString<'a> { turbo_tasks::debug::ValueDebugFormatString::Async(Box::pin(async move { if depth == 0 { return Ok(stringify!(ComponentsForJs).to_string()); } use turbo_tasks::debug::{internal::*, ValueDebugFormat}; Ok(format!( "{:#?}", match self { ComponentsForJs { page, layout, error, loading, template, not_found, default, route, metadata, } => FormattingStruct::new_named_async( stringify!(ComponentsForJs), vec![ AsyncFormattingField::new( stringify!(page), turbo_tasks::macro_helpers::value_debug_format_field( page.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(layout), turbo_tasks::macro_helpers::value_debug_format_field( layout.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(error), turbo_tasks::macro_helpers::value_debug_format_field( error.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(loading), turbo_tasks::macro_helpers::value_debug_format_field( loading.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(template), turbo_tasks::macro_helpers::value_debug_format_field( template.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(not_found), turbo_tasks::macro_helpers::value_debug_format_field( not_found.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(default), turbo_tasks::macro_helpers::value_debug_format_field( default.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(route), turbo_tasks::macro_helpers::value_debug_format_field( route.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(metadata), turbo_tasks::macro_helpers::value_debug_format_field( metadata.value_debug_format(depth.saturating_sub(1)) ), ), ], ) .await, } )) })) } } ``` </details>
ForsakenHarmony
pushed a commit
to vercel/next.js
that referenced
this pull request
Aug 1, 2024
…#8239) I noticed that `ValueDebugFormat` was pretty common near the top of `cargo llvm-lines`. It looked like this was probably due to the large number of await points inserted into the code. Each await point complicates the state machine that rustc must generate and pass to LLVM. This reduces the number of await points from one per field to one per struct. There's a minor change in behavior as the child fields are awaited concurrently (`join_all`) instead of one-at-a-time. ## Why? Less code generated by macros and passed to LLVM should mean faster compiles and a smaller binary that we're shipping to the user. The total change here is pretty small though, so it's probably not worth benchmarking compile times. ## Testing ``` cargo test -p turbo-tasks-macros-tests ``` ## cargo llvm-lines (sanity check) ``` cargo llvm-lines -p next-swc-napi ``` Before: ``` Lines Copies Function name ----- ------ ------------- 1094257 31851 (TOTAL) ... 1246 (0.1%, 2.2%) 1 (0.0%, 0.0%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` After: ``` Lines Copies Function name ----- ------ ------------- 1088974 31851 (TOTAL) ... 462 (0.0%, 7.7%) 1 (0.0%, 0.3%) <next_swc_napi[a7ff9ed323af314d]::app_structure::ComponentsForJs as turbo_tasks[129d614a87aad753]::debug::ValueDebugFormat>::value_debug_format::{closure#0} ``` ## Binary size (next-swc, stripped arm64 linux tarball) Before: `188180480 bytes` After: `187443200 bytes` <details> <summary><strong>Example Generated Code (After)</strong> </summary> ```rust // ================================================= // Recursive expansion of the ValueDebugFormat macro // ================================================= impl turbo_tasks::debug::ValueDebugFormat for ComponentsForJs { fn value_debug_format<'a>( &'a self, depth: usize, ) -> turbo_tasks::debug::ValueDebugFormatString<'a> { turbo_tasks::debug::ValueDebugFormatString::Async(Box::pin(async move { if depth == 0 { return Ok(stringify!(ComponentsForJs).to_string()); } use turbo_tasks::debug::{internal::*, ValueDebugFormat}; Ok(format!( "{:#?}", match self { ComponentsForJs { page, layout, error, loading, template, not_found, default, route, metadata, } => FormattingStruct::new_named_async( stringify!(ComponentsForJs), vec![ AsyncFormattingField::new( stringify!(page), turbo_tasks::macro_helpers::value_debug_format_field( page.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(layout), turbo_tasks::macro_helpers::value_debug_format_field( layout.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(error), turbo_tasks::macro_helpers::value_debug_format_field( error.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(loading), turbo_tasks::macro_helpers::value_debug_format_field( loading.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(template), turbo_tasks::macro_helpers::value_debug_format_field( template.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(not_found), turbo_tasks::macro_helpers::value_debug_format_field( not_found.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(default), turbo_tasks::macro_helpers::value_debug_format_field( default.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(route), turbo_tasks::macro_helpers::value_debug_format_field( route.value_debug_format(depth.saturating_sub(1)) ), ), AsyncFormattingField::new( stringify!(metadata), turbo_tasks::macro_helpers::value_debug_format_field( metadata.value_debug_format(depth.saturating_sub(1)) ), ), ], ) .await, } )) })) } } ``` </details>
ForsakenHarmony
pushed a commit
to vercel/next.js
that referenced
this pull request
Aug 14, 2024
# Turbopack * vercel/turborepo#8272 <!-- Donny/강동윤 - feat: Update `swc_core` to `v0.92.8` --> * vercel/turborepo#8262 <!-- Alexander Lyon - add crate to calculate prehashes --> * vercel/turborepo#8174 <!-- Tobias Koppers - use prehash to avoid rehashing the key in the task cache --> * vercel/turborepo#7674 <!-- Alexander Lyon - [turbo trace] add ability to filter by value and occurences --> * vercel/turborepo#8287 <!-- Donny/강동윤 - feat: Update `swc_core` to `v0.92.10` --> * vercel/turborepo#8037 <!-- Alexander Lyon - create turbo-static for compile time graph analysis --> * vercel/turborepo#8293 <!-- Will Binns-Smith - Sync Cargo.lock with Next.js --> * vercel/turborepo#8239 <!-- Benjamin Woodruff - Reduce amount of code generated by ValueDebugFormat --> * vercel/turborepo#8304 <!-- Benjamin Woodruff - Minor optimizations to the codegen of TaskFnInputFunction --> * vercel/turborepo#8221 <!-- Donny/강동윤 - perf: Introduce `RcStr` --> ### What? I tried using `Arc<String>` in vercel/turborepo#7772, but a team member suggested creating a new type so we can replace underlying implementation easily in the future. ### Why? To reduce memory usage. ### How? Closes PACK-2776
ForsakenHarmony
pushed a commit
to vercel/next.js
that referenced
this pull request
Aug 15, 2024
* vercel/turborepo#8272 <!-- Donny/강동윤 - feat: Update `swc_core` to `v0.92.8` --> * vercel/turborepo#8262 <!-- Alexander Lyon - add crate to calculate prehashes --> * vercel/turborepo#8174 <!-- Tobias Koppers - use prehash to avoid rehashing the key in the task cache --> * vercel/turborepo#7674 <!-- Alexander Lyon - [turbo trace] add ability to filter by value and occurences --> * vercel/turborepo#8287 <!-- Donny/강동윤 - feat: Update `swc_core` to `v0.92.10` --> * vercel/turborepo#8037 <!-- Alexander Lyon - create turbo-static for compile time graph analysis --> * vercel/turborepo#8293 <!-- Will Binns-Smith - Sync Cargo.lock with Next.js --> * vercel/turborepo#8239 <!-- Benjamin Woodruff - Reduce amount of code generated by ValueDebugFormat --> * vercel/turborepo#8304 <!-- Benjamin Woodruff - Minor optimizations to the codegen of TaskFnInputFunction --> * vercel/turborepo#8221 <!-- Donny/강동윤 - perf: Introduce `RcStr` --> I tried using `Arc<String>` in vercel/turborepo#7772, but a team member suggested creating a new type so we can replace underlying implementation easily in the future. To reduce memory usage. Closes PACK-2776
ForsakenHarmony
pushed a commit
to vercel/next.js
that referenced
this pull request
Aug 16, 2024
* vercel/turborepo#8272 <!-- Donny/강동윤 - feat: Update `swc_core` to `v0.92.8` --> * vercel/turborepo#8262 <!-- Alexander Lyon - add crate to calculate prehashes --> * vercel/turborepo#8174 <!-- Tobias Koppers - use prehash to avoid rehashing the key in the task cache --> * vercel/turborepo#7674 <!-- Alexander Lyon - [turbo trace] add ability to filter by value and occurences --> * vercel/turborepo#8287 <!-- Donny/강동윤 - feat: Update `swc_core` to `v0.92.10` --> * vercel/turborepo#8037 <!-- Alexander Lyon - create turbo-static for compile time graph analysis --> * vercel/turborepo#8293 <!-- Will Binns-Smith - Sync Cargo.lock with Next.js --> * vercel/turborepo#8239 <!-- Benjamin Woodruff - Reduce amount of code generated by ValueDebugFormat --> * vercel/turborepo#8304 <!-- Benjamin Woodruff - Minor optimizations to the codegen of TaskFnInputFunction --> * vercel/turborepo#8221 <!-- Donny/강동윤 - perf: Introduce `RcStr` --> I tried using `Arc<String>` in vercel/turborepo#7772, but a team member suggested creating a new type so we can replace underlying implementation easily in the future. To reduce memory usage. Closes PACK-2776
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I noticed that
ValueDebugFormat
was pretty common near the top ofcargo llvm-lines
. It looked like this was probably due to the large number of await points inserted into the code. Each await point complicates the state machine that rustc must generate and pass to LLVM.This reduces the number of await points from one per field to one per struct. There's a minor change in behavior as the child fields are awaited concurrently (
join_all
) instead of one-at-a-time.Why?
Less code generated by macros and passed to LLVM should mean faster compiles and a smaller binary that we're shipping to the user. The total change here is pretty small though, so it's probably not worth benchmarking compile times.
Testing
cargo llvm-lines (sanity check)
Before:
After:
Binary size (next-swc, stripped arm64 linux tarball)
Before:
188180480 bytes
After:
187443200 bytes
Example Generated Code (After)