Performance regression in 1.84 for inline-able function in closure
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
I tried this code:
#[macro_use]
extern crate criterion;
use criterion::Criterion;
use rand::Rng;
// #[inline(never)]
pub fn sum_all(v: &[i32]) -> i32 {
v.iter().fold(0i32, |a, b| curried_add(a)(*b))
}
fn curried_add(a: i32) -> Box<dyn Fn(i32) -> i32> {
Box::new(move |b| a + b)
}
fn criterion_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("bg");
let vals = generate_array(100_000);
group.bench_function("sum", |b| {
b.iter(|| {
let sum = sum_all(criterion::black_box(&vals));
criterion::black_box(sum);
})
});
}
fn generate_array(len: usize) -> Vec<i32> {
let mut rng = rand::rng();
(0..len).map(|_| rng.random_range(0..100)).collect()
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
I expected to see this happen: ~26 µs reported by cargo bench
Instead, this happened: ~1.4 ms reported by cargo bench
Version it worked on
It most recently worked on: 1.83.0
$ cargo clean; caffeinate -sd cargo +1.84.1 bench -q -- --save-baseline 1.84.1 && caffeinate -sd cargo +1.83.0 bench -q -- --save-baseline 1.83.0
Removed 1043 files, 228.6MiB total
Benchmarking bg/sum: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 6.7s, enable flat sampling, or reduce sample count to 60.
bg/sum time: [1.3761 ms 1.4096 ms 1.4473 ms]
Found 17 outliers among 100 measurements (17.00%)
1 (1.00%) low severe
16 (16.00%) high severe
bg/sum time: [26.609 µs 26.640 µs 26.679 µs]
Found 10 outliers among 100 measurements (10.00%)
5 (5.00%) high mild
5 (5.00%) high severe
Version with regression
rustc --version --verbose:
rustc 1.84.1 (e71f9a9a9 2025-01-27)
binary: rustc
commit-hash: e71f9a9a98b0faf423844bf0ba7438f29dc27d58
commit-date: 2025-01-27
host: aarch64-apple-darwin
release: 1.84.1
LLVM version: 19.1.5
Backtrace
no compiler crash
#inline
If I uncomment #[inline(never)] line, the performance is back to normal under 1.84.
bisecting output
searched nightlies: from nightly-2024-10-13 to nightly-2024-11-22
regressed nightly: nightly-2024-11-04
searched commit range: https://github.com/rust-lang/rust/compare/b3f75cc872cfd306860c3ad76a239e719015f855...b8c8287a229cd79604aa84c25e1235fc78cd5f2e
regressed commit: https://github.com/rust-lang/rust/commit/e3a918ece026cec748fc64af5b4983095b46097e
bisected with cargo-bisect-rustc v0.6.9
Host triple: aarch64-apple-darwin
Reproduce with:
cargo bisect-rustc --start 1.83.0 --end 1.84.1 --prompt -- bench -q
e3a918ece026cec748fc64af5b4983095b46097e comes from https://github.com/rust-lang/rust/pull/132542
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the regression with the provided Criterion benchmark and the cargo-bisect-rustc command, then inspect regressed commit e3a918ece026cec748fc64af5b4983095b46097e and PR 132542. Determine why the closure's inline-able function becomes slow in Rust 1.84.1; done means the benchmark returns near the 1.83 performance without requiring #[inline(never)].
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100