Description
I have been working on Rust compiler performance, guided by this analysis document that looks at compilation of 800 popular crates. It identifies tinyvec
as an interesting case, being the only crate out of those 800 to cause the diverge_cleanup
function within the compiler to be very hot.
I just looked into this, and it's caused by the very large array literals in the various default
methods within generated_impl.rs
. I don't see an easy way to speed up the compiler's handling of these literals, and the rarity of this case suggests it's not worth much effort to improve.
Fortunately, there's an alternative solution already present in tinyvec
: the rustc_1_55
feature uses const generics to avoid the need for generated_impl.rs
. I just did some simple benchmarking, and tinyvec-1.6.0
compiles about twice as fast when rustc_1_55
is enabled. Here are numbers for three kinds of non-incremental builds.
build kind | default | rustc_1_55 |
---|---|---|
check | 0.633s | 0.326s |
debug | 0.681s | 0.320s |
release | 0.703s | 0.385s |
There are several possible ways to make the faster compile times more widely available.
- Increase the minimum supported Rust version to 1.55.
- Failing that, change the structure of the features so that the default feature set uses const generics and users with pre-1.55 versions can opt into the generated code. This would presumably require at least a minor version change.
- Failing that, add documentation about the
rustc_1_55
, which currently isn't mentioned in the README or the rustdocs.
Defaults matter, so the first or second option would be preferable.
It's also possible to use a build.rs
to auto-detect the Rust version being used, but compiling and running the build script takes a non-trivial amount of time and would eat into the savings, so I don't recommend doing that.
Anyway, I hope this is useful information! Fast compile times are good for everybody :) I'm happy to answer any questions you might have.