-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-codegenArea: Code generationArea: Code generationC-bugCategory: This is a bug.Category: This is a bug.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.Issue: Problems and improvements with respect to binary size of generated code.
Description
Godbolt link https://godbolt.org/z/cMdx6v1G9
pub fn exact_size(){
let it = std::hint::black_box(vec![1,2,3].into_iter());
let v = it.collect::<Vec<_>>();
std::hint::black_box(v);
}
pub fn var_size(){
let it = std::hint::black_box(vec![1,2,3].into_iter()).filter(|x| true);
let v = it.collect::<Vec<_>>();
std::hint::black_box(v);
}
I expected to see this happen: exact_size
to generate better assembly than var_size
Instead, this happened:
var_size
generates way shorter assembly (~90) thanexact size
(>200) with zero call to allocateVec
- It seems to me
var_size
is trying to allocate theVec
on stack. This optimization did not happen onexact_size
(Excuse me if I misintepreted the assembly).
The key to trigger this deoptimization seems to be mutating the iterator before collecting. This example is a reduction of a real-world code where the first few elements are processed differently and the rest of the elements is collected into Vec
then consumed locally.
Godbolt link for a more realistic example: https://godbolt.org/z/sccdTcvh6
#[inline(never)]
pub fn example<I: Iterator>(mut it: I){
// .... read and process a few elements
let Some(first_elem) = it.next() else {return;};
// let mut it = it.filter(|x| true); // <------ This causes different optimization if ExactSizeIterator
let v = it.collect::<Vec<_>>();
for elem in v {
// Different processing on rest of the elements.
}
}
pub fn call_example() {
example(vec![1,2,3].into_iter())
}
Edit: Include a more realistic example
Metadata
Metadata
Assignees
Labels
A-codegenArea: Code generationArea: Code generationC-bugCategory: This is a bug.Category: This is a bug.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.Issue: Problems and improvements with respect to binary size of generated code.