perf(ast): re-order struct fields to reduce padding#11056
perf(ast): re-order struct fields to reduce padding#11056graphite-app[bot] merged 1 commit intomainfrom
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
CodSpeed Instrumentation Performance ReportMerging #11056 will not alter performanceComparing Summary
|
791fbbb to
f54800c
Compare
|
Perf impact is much less than I'd hoped. Only sub-% movement on parser benchmarks, and 1% on a couple of transformer/minifier benchmarks. Meh! Still, why not? It's crazy to be using memory for padding bytes. And now we don't risk perf regressions if we rearrange fields or add more fields in future. There is one quite large annoyance. Rustdoc seems to work from the types after proc macros have run, so now the fields in docs for |
f54800c to
00d5da8
Compare
|
The Rustdoc issue is now fixed. Rustdoc now shows struct fields in original source order. |
00d5da8 to
7e0b283
Compare
Merge activity
|
All our AST structs are `#[repr(C)]`, which gives us guaranteed stable memory layouts. This is essential for raw transfer, and helpful for other purposes too. However, the downside is that we lose out on the automatic field-reordering that default `#[repr(Rust)]` provides, where structs are packed to minimize padding bytes. This PR implements a similar field-reordering scheme, to get the same effect. * `oxc_ast_tools` determines optimal field order for compact memory layout. * `oxc_ast_tools` generates a file (`structs.rs`) which details the desired field order for each type. * `#[ast]` proc macro follows the instructions in `structs.rs` and re-orders the fields. This reduces the size of various AST types by 8 bytes. No type now has more than 7 padding bytes (previously e.g. `Function` had 15 bytes of padding). Possible future improvements: 1. Get Rust Analyser to display original field order. 2. Remove `syn` dependency from `oxc_ast_macros` crate, to improve compile times. It should be possible to do all the AST manipulation using just `proc_macro` crate, by generating more code in `oxc_ast_tools`, so the macro's logic can be simpler. Note: This PR doesn't add `syn` dependency, it was already there. But it makes it easier to remove it.
7e0b283 to
e3e60eb
Compare
All our AST structs are `#[repr(C)]`, which gives us guaranteed stable memory layouts. This is essential for raw transfer, and helpful for other purposes too. However, the downside is that we lose out on the automatic field-reordering that default `#[repr(Rust)]` provides, where structs are packed to minimize padding bytes. This PR implements a similar field-reordering scheme, to get the same effect. * `oxc_ast_tools` determines optimal field order for compact memory layout. * `oxc_ast_tools` generates a file (`structs.rs`) which details the desired field order for each type. * `#[ast]` proc macro follows the instructions in `structs.rs` and re-orders the fields. This reduces the size of various AST types by 8 bytes. No type now has more than 7 padding bytes (previously e.g. `Function` had 15 bytes of padding). Possible future improvements: 1. Get Rust Analyser to display original field order. 2. Remove `syn` dependency from `oxc_ast_macros` crate, to improve compile times. It should be possible to do all the AST manipulation using just `proc_macro` crate, by generating more code in `oxc_ast_tools`, so the macro's logic can be simpler. Note: This PR doesn't add `syn` dependency, it was already there. But it makes it easier to remove it.
e3e60eb to
2b0a69f
Compare

All our AST structs are
#[repr(C)], which gives us guaranteed stable memory layouts. This is essential for raw transfer, and helpful for other purposes too.However, the downside is that we lose out on the automatic field-reordering that default
#[repr(Rust)]provides, where structs are packed to minimize padding bytes.This PR implements a similar field-reordering scheme, to get the same effect.
oxc_ast_toolsdetermines optimal field order for compact memory layout.oxc_ast_toolsgenerates a file (structs.rs) which details the desired field order for each type.#[ast]proc macro follows the instructions instructs.rsand re-orders the fields.This reduces the size of various AST types by 8 bytes. No type now has more than 7 padding bytes (previously e.g.
Functionhad 15 bytes of padding).Possible future improvements:
syndependency fromoxc_ast_macroscrate, to improve compile times. It should be possible to do all the AST manipulation using justproc_macrocrate, by generating more code inoxc_ast_tools, so the macro's logic can be simpler.Note: This PR doesn't add
syndependency, it was already there. But it makes it easier to remove it.