ModularM
Modular13mo ago
4 replies
duck_tape

Mojo for-loop performance

https://github.com/sstadick/rust-vs-mojo-loop

While profiling other code, trying to get my perf to match Rust, I noticed that my vanilla for-loop seemed to be one large source of difference. I'm not great with assembly, but looking at what was generated it seemed like Rust was able to skip bound checks when indexing into the arrays since the length of the array was/is given in the range.

Has anyone else ran into this? While this is a toy example, I've run into in more complex scenarios and with real data as well.

The two programs in question, repo has benching script:

import sys


fn main() raises:
    var times = sys.argv()[1].__int__()

    var array = List[UInt64]()
    for i in range(0, times):
        array.append(i)

    var sum: UInt64 = 0
    for _ in range(0, times):
        for i in range(0, times):
            sum += array[i]
    print(sum)


use std::env::args;

fn main() {
    let times = args()
        .skip(1)
        .next()
        .unwrap()
        .parse::<usize>()
        .expect("Expected number as first arg");

    // I don't think filling the array with the macro has any hidden optimizations, but just in case:
    let mut array: Vec<u64> = vec![];
    for i in 0..times {
        array.push(i as u64)
    }

    let mut sum = 0;
    for _ in 0..times {
        for i in 0..times {
            sum += array[i];
        }
    }
    println!("{}", sum)
}
GitHub
Contribute to sstadick/rust-vs-mojo-loop development by creating an account on GitHub.
GitHub - sstadick/rust-vs-mojo-loop
Was this page helpful?