Skip to content

Instantly share code, notes, and snippets.

@AlexDaniel
Created February 28, 2023 18:56
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Using a native int for the loop variable gives a MASSIVE performance boost

Note: the code below comes from a solution to one of the basic introductory programming tasks (i.e. people learning about loops and stuff). Of course, the algorithm itself can be improved a lot, but the point here is about the raw performance of compilers, and not about the algorithm or code style. The task was to find a number within the range with the biggest sum of its divisors. I just got curious as to how different compilers will handle the “same” code, and this is where I noticed that in Rakudo something is a bit weird.

For the code below, changing for $a..$b -> $i { to for $a..$b -> int $i { gives a 10x time boost for the entire program. Doing the same but with uint does not work as fast.

Just as a reference, without native ints the program runs significantly slower than the python version, but after changing the loop variable it runs significantly faster than the python version.

Raku (without int) 168.622s
Raku (with int) 12.261s
Python 43.420s
Rust 1.816s

Code (slow):

#!/usr/bin/env raku
my $a = +prompt;
my $b = +prompt;
my $max = 0;
my $x = 0;
for $a..$b -> $i {
    my $sum = 0;
    for 1..$i -> $j {
        if $i %% $j {
            $sum += $j;
        }
    }
    if $sum >= $max {
        $max = $sum;
        $x = $i;
    }
}
say $x $max;

Code (fast):

#!/usr/bin/env raku
my $a = +prompt;
my $b = +prompt;
my $max = 0;
my $x = 0;
for $a..$b -> int $i { #← this line was changed
    my $sum = 0;
    for 1..$i -> int $j { #← this line was changed
        if $i %% $j {
            $sum += $j;
        }
    }
    if $sum >= $max {
        $max = $sum;
        $x = $i;
    }
}
say $x $max;
Code (Python)
#!/usr/bin/env python3
a = int(input())
b = int(input())
_max = 0
for i in range(a, b + 1):
    _sum = 0
    for j in range(1, i + 1):
        if i % j == 0:
            _sum += j

    if _sum >= _max:
        _max = _sum
        x = i

print(x, _max)
Code (Rust)
use std::io;

fn main() {
    let mut input_line1 = String::new();
    let mut input_line2 = String::new();

    io::stdin().read_line(&mut input_line1).expect("Failed to read a");
    let a: u32 = input_line1.trim().parse().expect("a is not an integer");

    io::stdin().read_line(&mut input_line2).expect("Failed to read b");
    let b: u32 = input_line2.trim().parse().expect("b is not an integer");

    let mut max = 0;
    let mut x = 0;
    for i in a..=b {
        let mut sum = 0;

        for j in 1..=i {
            if i % j == 0 {
              sum += j;
            }
        }
        if sum >= max {
            max = sum;
            x = i;
        }
    }
    println!("{x} {max}");
}
Welcome to Rakudo™ v2022.12-1-gd52342eb0.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2022.12.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment