Skip to content

Instantly share code, notes, and snippets.

@AlexDaniel
Created February 28, 2023 18:56
Show Gist options
  • Save AlexDaniel/d651dd9eb21df5ad94ccfa25af11d30e to your computer and use it in GitHub Desktop.
Save AlexDaniel/d651dd9eb21df5ad94ccfa25af11d30e to your computer and use it in GitHub Desktop.
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