I made a crate that involves generating Rust types from some C code with a proc macro. This works surprisingly well, except for one thing: compile times.
There are a few hundred of the generated types (500-ish) and the crate takes ~8 seconds to build on my machine (Ryzen 7900). The bottleneck isn't codegen, but rather type checking and borrow checking:
time: 2.159; rss: 372MB -> 575MB ( +202MB) type_check_crate
time: 1.800; rss: 575MB -> 817MB ( +242MB) MIR_borrow_checking
This is from the code at A few build perf improvements by gnosek · Pull Request #43 · falcosecurity/plugin-sdk-rs · GitHub where I managed to cut down the build time by ~800ms by reducing the use of generics, but it's still slower than I'd hope. Not enabling the new full-schema
feature makes the crate compile in ~2 seconds (as there are only 2 event types to handle, not hundreds) but I'd like to always support the full event schema if possible with reasonable build times.
With -Znext-solver
, the type checking time explodes:
time: 32.740; rss: 374MB -> 612MB ( +239MB) type_check_crate
(before this PR it was >1 minute I think).
With -Znext-solver=coherence
, it's roughly the same as on stable:
time: 2.091; rss: 376MB -> 576MB ( +200MB) type_check_crate
The generated code looks like this (except with the full-schema
feature, there are ~500 types, not 2, but that's not really human-readable):
I don't see anything particularly egregious in the generated code (except at the end, where it looks like the formatter gave up), so am I missing some low hanging fruit or should I just accept the compile times?
While I was writing this post, I tried making this: plugin-sdk-rs/falco_event_derive/src/event_info.rs at main · falcosecurity/plugin-sdk-rs · GitHub into a free function (so we don't cast Self to a trait). It looked like it helped a lot but then I couldn't reliably reproduce the difference, so maybe it was a fluke after all.