Skip to content

step_by() on new ranges is less optimized than the old ranges. #157754

@theemathas

Description

@theemathas

I compiled the following code:

#[unsafe(no_mangle)]
fn a(n: u32, callback: fn(u32)) {
    let range = 0..n;
    for x in range.step_by(2) {
        callback(x);
    }
}

#[unsafe(no_mangle)]
fn b(n: u32, callback: fn(u32)) {
    let range = std::range::Range { start: 0, end: n }.into_iter();
    for x in range.step_by(2) {
        callback(x);
    }
}

Ideally, both functions should compile to the same or similar assembly. Instead, the inner loop of b is clearly worse than that of a:

Godbolt

Assembly code
a:
        push    rbp
        push    r14
        push    rbx
        mov     ebp, edi
        shr     ebp
        cmp     edi, ebp
        je      .LBB0_3
        mov     rbx, rsi
        sub     ebp, edi
        xor     edi, edi
.LBB0_2:
        lea     r14d, [rdi + 2]
        call    rbx
        mov     edi, r14d
        inc     ebp
        jne     .LBB0_2
.LBB0_3:
        pop     rbx
        pop     r14
        pop     rbp
        ret

b:
        test    edi, edi
        je      .LBB1_5
        push    rbp
        push    r14
        push    rbx
        mov     rbx, rsi
        mov     ebp, edi
        mov     r14d, 2
.LBB1_2:
        lea     edi, [r14 - 2]
        call    rbx
        test    r14d, r14d
        je      .LBB1_4
        cmp     r14d, ebp
        lea     eax, [r14 + 2]
        mov     r14d, eax
        jb      .LBB1_2
.LBB1_4:
        pop     rbx
        pop     r14
        pop     rbp
.LBB1_5:
        ret

I believe that this is because step_by has a specialized implementation for the old ranges, but not for the new ranges. See https://github.com/rust-lang/rust/blob/485ec3fbcc12fa14ef6596dabb125ad710499c9e/library/core/src/iter/adapters/step_by.rs

Meta

Reproducible on godbolt with version

rustc 1.98.0-nightly (485ec3fbc 2026-06-10)
binary: rustc
commit-hash: 485ec3fbcc12fa14ef6596dabb125ad710499c9e
commit-date: 2026-06-10
host: x86_64-unknown-linux-gnu
release: 1.98.0-nightly
LLVM version: 22.1.6
Internal compiler ID: nightly

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-iteratorsArea: IteratorsA-specializationArea: Trait impl specializationC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchF-new_range`#![feature(new_range)]`I-slowIssue: Problems and improvements with respect to performance of generated code.T-libsRelevant to the library team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    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