Skip to content

Every access to a module-level list constant re-materializes the list #10219

Description

@niclas-ahden

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions