-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Description
I recently added a new -Zmacro-stats
option to the Rust compiler, which prints measurements on the size of code generated by macros. I soon heard that Bevy's #[derive(Reflect)]
is generating large amounts of code.
For example, consider the bevy_ui
crate. It is around 16,000 lines of code, and 563,000 bytes of text. Here are the top five entries in the -Zmacro-stats
output:
MACRO EXPANSION STATS: bevy_ui
Macro Name Uses Lines Avg Lines Bytes Avg Bytes
-----------------------------------------------------------------------------------
#[derive(Reflect)] 73 27_407 375.4 1_544_696 21_160.2
#[derive(QueryData)] 2 1_695 847.5 99_092 49_546.0
#[derive(Component)] 47 1_368 29.1 70_043 1_490.3
#[derive(Debug)] 88 930 10.6 38_349 435.8
#[derive(PartialEq)] 76 792 10.4 34_317 451.5
All the #[derive(Reflect)]
invocations in bevy_ui
produce more than 1.5MB of source code, an average of 21KB per invocation. That's about 3x the size of the original code, and more than 15x the size of the next biggest derive.
The generated code for a simple example can be seen here. It is very verbose and contains multiple redundancies.
All this code has to be processed by the compiler: parsed, type-checked, borrow-checked, optimized, and codegen'd. Reducing the size of the generated code could improve compile times for Bevy projects significantly.