Home > Back-end >  Why is my Rust program running more that twice as slow as the Java equivalent?
Why is my Rust program running more that twice as slow as the Java equivalent?

Time:12-29

I have a program that finds, for all integers less than or equal to the input, numbers that can be represented as the sum of two cubes, twice, aka the Ramanujan's number problem.

I have written this in Java and Rust, however, it runs more than twice as slow in Rust as compared to Java.

Is there anything I can do to make it perform better, or otherwise improve it? Thanks!

Rust code:

use num_integer::Roots;
fn main() {
    let v = 984067;
    // let v = 87539319;
    for i in 1..=v {
        ramanujan(i)
    }
}
fn ramanujan(m: i32) {
    let maxcube = m.cbrt();
    let mut res1 = 0;
    let mut res2 = 0;
    let mut _res3 = 0;
    let mut _res4 = 0;
    for i in 1..=maxcube {
        for j in 1..=maxcube {
            if i * i * i   j * j * j == m {
                res1 = i;
                res2 = j;
                break;
            }
        }
    }
    for k in 1..=maxcube {
        for l in 1..=maxcube {
            if k == res1 || k == res2 || l == res1 || l == res2 {
                continue;
            }
            if k * k * k   l * l * l == m {
                _res3 = k;
                _res4 = l;
                break;
            }
        }
    }
    // if ((res1 * res1 * res1)   (res2 * res2 * res2) == m) && ((res3 * res3 * res3)   (res4 * res4 * res4) == m) {
    //     println!("{} is representable as the sums of two different sets of two cubes!\nThese values are {}, {}, and {}, {}.", m, res1, res2, res3, res4);
    // }
}

Java code:

public class Ramun {
    public static void main(String[] args) {
        int v = 984067;
        // int v = 87539319;
        for (int i = 1; i <= v; i  ) {
            ramanujan(i);
        }
    }

    public static void ramanujan(int m) {
        int maxcube = (int) Math.round(Math.cbrt(m));
        int res1 = 0, res2 = 0, res3 = 0, res4 = 0;
        for (int i = 1; i <= maxcube; i  ) {
            for (int j = 1; j <= maxcube; j  ) {
                if (((i * i * i)   (j * j * j)) == m) {
                    res1 = i;
                    res2 = j;
                    break;
                }
            }
        }
        for (int k = 1; k <= maxcube; k  ) {
            for (int l = 1; l <= maxcube; l  ) {
                if (k == res1 || k == res2 || l == res1 || l == res2)
                    continue;
                if (((k * k * k)   (l * l * l)) == m) {
                    res3 = k;
                    res4 = l;
                    break;
                }
            }
        }
        // if (((res1 * res1 * res1)   (res2 * res2 * res2) == m) && ((res3 * res3 * res3)   (res4 * res4 * res4) == m)) {
        //     System.out.printf("%d is representable as the sums of two different sets of two cubes!%nThese values are %d, %d, and %d, %d.%n", m, res1, res2, res3, res4);
        // }
    }
}

Time output for both programs

CodePudding user response:

The problem lies in RangeInclusive. It can be costly:

use num_integer::Roots;

fn main() {
    let v = 984067;
    for i in 1..=v {
        ramanujan(i)
    }
}

fn ramanujan(m: i32) {
    let maxcube = m.cbrt()   1; // we know it can't overflow
    let mut res1 = 0;
    let mut res2 = 0;
    let mut res3 = 0;
    let mut res4 = 0;
    for i in 1..maxcube {
        for j in 1..maxcube {
            if i * i * i   j * j * j == m {
                res1 = i;
                res2 = j;
                break;
            }
        }
    }
    for k in 1..maxcube {
        for l in 1..maxcube {
            if k == res1 || k == res2 || l == res1 || l == res2 {
                continue;
            }
            if k * k * k   l * l * l == m {
                res3 = k;
                res4 = l;
                break;
            }
        }
    }
}

Result:

From: 0.01s user 0.00s system 0% cpu 17.993 total
To: 0.00s user 0.01s system 0% cpu 3.494 total

Add a comment to #45222 to draw attention to this issue.

  • Related