I must be hitting some weird edge case inside Rust or LLVM where I'm right
on the line between inlining or not a block of code. I've been playing
around with the collatz fns from:

http://www.mit.edu/~mtikekar/posts/stream-fusion.html

but I stumbled upon two weird mis-optimizations at --opt-level=2 and
--opt-level=3. It appears that my code is *faster* when I call a function
indirectly through a closure *and* when I call `.clone()` on a uint. Here's
the main snippet of code:

```
fn collatz_next(a: uint) -> uint {
    (if a % 2 == 0 { a } else { 3 * a + 1 }) / 2
}

struct RecursiveIterator<'a> {
    priv value: uint,
    priv f: 'a |uint| -> uint,
}

fn collatz_len_fast(a0: uint) -> uint {
    let mut len = 0;
    let mut iter = RecursiveIterator { value: a0, f: collatz_next };

    loop {
        let a = {
            let value = iter.value;
            let a = iter.value.clone();
            // let a = iter.value;
            iter.value = (iter.f)(a);
            // iter.value = collatz_next(a);
            value
        };

        if a == 1 { break; }
        len += 1;
    }
    len
}
```

If I swap which code is commented out it is 18% slower, but I have no idea
why. Here's my gist that has all the code and my performance numbers:

https://gist.github.com/erickt/7725346

Does anyone have an idea of what's going on here?
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to