Open
Description
I tried this code:
use std::iter::successors;
pub fn foo_map(y: u32) -> Vec<u32> {
(0..).map(|i| y.pow(i)).take(5).collect()
}
pub fn foo_successors(y: u32) -> Vec<u32> {
successors(Some(1), |x| Some(y * x)).take(5).collect()
}
I expected to see this happen: the same performance
Instead, this happened: foo_successors
is ~2x slower than foo_map
, and the assembly outputted has a ton of checks. Changing foo_map
to (0..).map(|i| Some(y.pow(i)).take(5).collect::<Option<_>>().unwrap()
produces identical assembly (afaict, I have bad eyes :D), which leads me to believe it's because of Some
, which should be optimized out as it never returns None
.
Meta
rustc --version --verbose
:
rustc 1.72.0-nightly (fe7454bf4 2023-06-19)
binary: rustc
commit-hash: fe7454bf439c93cbe9ac8a8f7fcfacd5a40244c2
commit-date: 2023-06-19
host: x86_64-unknown-linux-gnu
release: 1.72.0-nightly
LLVM version: 16.0.5
@rustbot label +I-slow
Metadata
Metadata
Assignees
Labels
Area: IteratorsCategory: An issue proposing an enhancement or a PR with one.Category: An issue highlighting optimization opportunities or PRs implementing suchIssue: Problems and improvements with respect to performance of generated code.Relevant to the library team, which will review and decide on the PR/issue.