Skip to content

iter_mut is slightly slower than code with a manual for loop #144118

@hkBst

Description

@hkBst

Code using iter_mut is slightly slower than code with a manual for loop. Today's nightly results:

$ cargo bench
    Finished `bench` profile [optimized] target(s) in 0.01s
     Running unittests src/lib.rs (target/release/deps/bench_round_up-6e3523a74735e3c8)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running benches/bench.rs (target/release/deps/bench-f02e501c16b73b8b)

running 2 tests
test bench_round_up_for  ... bench:     730,833.00 ns/iter (+/- 1,163.95)
test bench_round_up_iter ... bench:     740,568.00 ns/iter (+/- 1,857.11)

test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured; 0 filtered out; finished in 0.88s

The functions:

pub fn round_up_iter(d: &mut [u8]) -> Option<u8> {
    match d.iter().rposition(|&c| c != b'9') {
        Some(i) => {
            // d[i+1..n] is all nines
            d[i] += 1;
            d.iter_mut().skip(i + 1).for_each(|c| *c = b'0');
            None
        }
        None if d.is_empty() => {
            // an empty buffer rounds up (a bit strange but reasonable)
            Some(b'1')
        }
        None => {
            // 999..999 rounds to 1000..000 with an increased exponent
            d[0] = b'1';
            d.iter_mut().skip(1).for_each(|c| *c = b'0');
            Some(b'0')
        }
    }
}

pub fn round_up_for(d: &mut [u8]) -> Option<u8> {
    match d.iter().rposition(|&c| c != b'9') {
        Some(i) => {
            // d[i+1..n] is all nines
            d[i] += 1;
            for j in i + 1..d.len() {
                d[j] = b'0';
            }
            None
        }
        None if d.len() > 0 => {
            // 999..999 rounds to 1000..000 with an increased exponent
            d[0] = b'1';
            for j in 1..d.len() {
                d[j] = b'0';
            }
            Some(b'0')
        }
        None => {
            // an empty buffer rounds up (a bit strange but reasonable)
            Some(b'1')
        }
    }
}

This holds even if the order of match arms is the same.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions