Reading a module-level list constant seems to cause a heap alloc+free for every read. A loop that reads one element per iteration from a 3-element top-level list is ~40x slower than the identical loop with the list passed as an argument. Scalar top-level constants are fine.
app [main!] {
pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.9/8GdFEvQYS3TeAZxKvTzCLVdQiomweGtXcdZkXNDEeABq.tar.zst",
}
import pf.Stdout
bases : List(U64)
bases = [1, 2, 3]
loop : U64, U64, U64 -> U64
loop = |i, n, acc|
if i >= n {
acc
} else {
loop(i + 1, n, acc + (bases.get(i % 3) ?? 0))
}
main! = |args| {
Stdout.line!("sum: ${loop(0, 1000000 + args.len(), 0).to_str()}")
Ok({})
}
roc main.roc takes 3.9s. Moving bases into main! and passing it as an argument to loop takes 0.09s.
Tested on NixOS, x86, Roc 0d86ed8b3f4e39a941a15677c64f3ac1ca17e8bb.
Reading a module-level list constant seems to cause a heap alloc+free for every read. A loop that reads one element per iteration from a 3-element top-level list is ~40x slower than the identical loop with the list passed as an argument. Scalar top-level constants are fine.
roc main.roctakes 3.9s. Movingbasesintomain!and passing it as an argument tolooptakes 0.09s.Tested on NixOS, x86, Roc
0d86ed8b3f4e39a941a15677c64f3ac1ca17e8bb.