← All questions

My program is slow

The short answer, in order of how much it usually buys:

  1. Compile itrakupp --exe -O prog.raku -o prog
  2. Check it is actually CPU-bound before doing anything else
  3. Avoid rebuilding big values in a loop

Compile it

rakupp --exe -O prog.raku -o prog && ./prog

Measured on the benchmark kernels, interpreter against --exe -O:

kernelinterpreter--exe -O
5M integer accumulation295ms32ms
fib(32), recursive calls672ms170ms
1M ** 3 then % 1000538ms52ms
primes < 200k by trial division1245ms25ms

That is where the big factors are: arithmetic in a loop, called functions, integer work. -O turns those into native operations instead of boxed values.

What it does not speed up:

kernelinterpreter--exe -O
400k string appends23ms23ms

String building, IO, regex and hash work are already doing the same underlying operations in both modes. If that is your program, compiling changes little — and --exe without -O is not the fast mode; the -O is what matters.

Check what you are actually measuring

my $t0 = now;
# … the part you suspect …
note "elapsed: ", (now - $t0).round(0.001), "s";

Startup is ~2ms, so for anything short you are timing the work, not the launch. If elapsed time is dominated by a run/shell call, a network round trip or reading a file, none of the above applies — you are waiting on something else.

Things that are slow in any Raku

Rebuilding a big value inside a loop. Appending to a string with ~= is in-place and cheap; $s = $s ~ $x is not, and neither is @a = @a, $x.

Sorting with a comparator when a key would do. .sort({ $^a.foo cmp $^b.foo }) calls your block on every comparison — O(n log n) times. .sort(*.foo) extracts the key once per element:

my @words = <delta alpha charlie bravo>;
say @words.sort(*.chars);       # key extraction — one call per element

Regexes rebuilt per iteration. Hoist a regex out of the loop if the pattern is constant.

Measuring a change

The repo has the harnesses used for its own numbers:

rakupp tools/perf-guard.raku       # interpreter hot path, ~10s
rakupp tools/run-bench.raku        # interpreter / --exe / Rakudo, 3-way
rakupp tools/run-optbench.raku     # --exe vs --exe -O, and verifies they agree

run-optbench checks that all four modes produce identical output before it reports a timing, so it catches an optimisation that changed an answer.

If you have a program where Raku++ is much slower than you expect — especially slower than Rakudo — that is worth reporting. Include the program.

---

Deeper detail: OPTIMIZATION.md for what -O does, BENCHMARKS.md for the full measured set.

Back to the FAQ index.