Skip to content

Performance regression with rustc 1.93+ #408

@glandium

Description

@glandium

Starting with rustc 1.93, wrapping a SmallVec in any struct causes rustc to emit code that zeroes the entire struct, instead of only touching the capacity field (which was the behavior until rustc 1.92).
The larger the Array in the SmallVec, the bigger the impact. In the real world, this caused a noticeable regression in a perf test in Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=2046376)
The rustc regression itself is filed here: rust-lang/rust#157743

This can be trivially reproduced by adding the following benchmark to benches/bench.rs:

#[bench]
fn bench_new_in_newtype(b: &mut Bencher) {
    struct Wrap(SmallVec<[u64; 32]>);
    b.iter(|| test::black_box(Wrap(SmallVec::new())))
}

On my machine the benchmark results look like this:

nightly-2025-11-23 (last good) nightly-2025-11-24 (first bad)
union 7.63ns 10.74ns
non-union 8.70ns 13.04ns

That is a significant overhead, and in a tight loop as in the case of Firefox, can lead to a large regression.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions