- 
        Couldn't load subscription status. 
- Fork 13.9k
Closed
Labels
I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.
Description
#![crate_type = "lib"]
struct R {
    start: i32,
    end: i32
}
impl Iterator for R
{
    type Item = i32;
    fn next(&mut self) -> Option<i32> {
        if self.start < self.end {
            let old = self.start;
            self.start += 1;
            Some(old)
        } else {
            None
        }
    }
}
pub fn test() -> usize {
    R { start: 0, end: 100000}.count()
}Compiles to:
_ZN4test20h08046f2c32b9b146kaaE:
    .cfi_startproc
    xorl    %ecx, %ecx
    movq    $-1, %rax
    .align  16, 0x90
.LBB0_1:
    cmpl    $100000, %ecx
    setl    %dl
    movzbl  %dl, %edx
    addl    %ecx, %edx
    incq    %rax
    cmpl    $100000, %ecx
    movl    %edx, %ecx
    jl  .LBB0_1
    retqIt should at least look something like:
    xorl    %eax, %eax
    movl    $100000, %ecx
.LBB0_1: 
    incl    %eax
    decl    %ecx
    jne .LBB0_1But really that case should be constant folded (clang folds the equivalent C for loop).
(NB. count is currently implemented as self.fold(0, |c, _| c + 1), and the bad codegen occurs if that is definition is used directly, and also if one uses the mutating for loop: let mut c = 0; for _ in ... { c += 1 }.)
This previously affected std::ops::Range (i.e. x..y), but #24705 implemented a work-around.
Metadata
Metadata
Assignees
Labels
I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.